簡體   English   中英

Firebase Firestore 從集合中獲取數據

[英]Firebase Firestore get data from collection

我想從我的 Firebase Firestore 數據庫中獲取數據。 我有一個名為 user 的集合,每個用戶都有一些相同類型的對象(我的 Java 自定義對象)的集合。 我想在創建 Activity 時用這些對象填充我的 ArrayList。

private static ArrayList<Type> mArrayList = new ArrayList<>();;

在 onCreate() 中:

getListItems();
Log.d(TAG, "onCreate: LIST IN ONCREATE = " + mArrayList);
*// it logs empty list here

調用方法以獲取要列出的項目:

private void getListItems() {
    mFirebaseFirestore.collection("some collection").get()
            .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                @Override
                public void onSuccess(QuerySnapshot documentSnapshots) {
                    if (documentSnapshots.isEmpty()) {
                        Log.d(TAG, "onSuccess: LIST EMPTY");
                        return;
                    } else {
                        for (DocumentSnapshot documentSnapshot : documentSnapshots) {
                            if (documentSnapshot.exists()) {
                                Log.d(TAG, "onSuccess: DOCUMENT" + documentSnapshot.getId() + " ; " + documentSnapshot.getData());
                                DocumentReference documentReference1 = FirebaseFirestore.getInstance().document("some path");
                                documentReference1.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                                    @Override
                                    public void onSuccess(DocumentSnapshot documentSnapshot) {
                                        Type type= documentSnapshot.toObject(Type.class);
                                        Log.d(TAG, "onSuccess: " + type.toString());
                                        mArrayList.add(type);
                                        Log.d(TAG, "onSuccess: " + mArrayList);
                                        /* these logs here display correct data but when
                                         I log it in onCreate() method it's empty*/
                                    }
                                });
                            }
                        }
                    }
                }
            }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Toast.makeText(getApplicationContext(), "Error getting data!!!", Toast.LENGTH_LONG).show();
        }
    });
}

get()操作返回一個Task<>這意味着它是一個異步操作 調用getListItems()只會啟動操作,不會等待操作完成,這就是您必須添加成功和失敗偵聽器的原因。

盡管您對操作的異步性質無能為力,但您可以按如下方式簡化代碼:

private void getListItems() {
    mFirebaseFirestore.collection("some collection").get()
            .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                @Override
                public void onSuccess(QuerySnapshot documentSnapshots) {
                    if (documentSnapshots.isEmpty()) {
                        Log.d(TAG, "onSuccess: LIST EMPTY");
                        return;
                    } else {
                        // Convert the whole Query Snapshot to a list
                        // of objects directly! No need to fetch each
                        // document.
                        List<Type> types = documentSnapshots.toObjects(Type.class);   

                        // Add all to your list
                        mArrayList.addAll(types);
                        Log.d(TAG, "onSuccess: " + mArrayList);
                    }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Toast.makeText(getApplicationContext(), "Error getting data!!!", Toast.LENGTH_LONG).show();
                }
            });
}

試試這個..工作正常。下面的函數也將從 firebse 獲取實時更新..

db = FirebaseFirestore.getInstance();


        db.collection("dynamic_menu").addSnapshotListener(new EventListener<QuerySnapshot>() {
            @Override
            public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {

                if (e !=null)
                {

                }

                for (DocumentChange documentChange : documentSnapshots.getDocumentChanges())
                {
                 String   isAttendance =  documentChange.getDocument().getData().get("Attendance").toString();
                 String  isCalender   =  documentChange.getDocument().getData().get("Calender").toString();
                 String isEnablelocation = documentChange.getDocument().getData().get("Enable Location").toString();

                   }
                }
        });

更多參考: https : //firebase.google.com/docs/firestore/query-data/listen

如果您不想實時更新,請參閱下面的文檔

https://firebase.google.com/docs/firestore/query-data/get-data

    db.collection("users").get().then((querySnapshot) => {
    querySnapshot.forEach((doc) => {
        console.log(`${doc.id} => ${doc.data()}`);
    });

來源:- https://firebase.google.com/docs/firestore/quickstart

這是一個簡化的示例:

在 Firebase 中創建一個集合“DownloadInfo”。

並在其中添加一些包含這些字段的文檔:

文件名(字符串)、id(字符串)、大小(數字)

創建您的課程:

public class DownloadInfo {
    public String file_name;
    public String id;
    public Integer size;
}

獲取對象列表的代碼:

FirebaseFirestore db = FirebaseFirestore.getInstance();

db.collection("DownloadInfo")
        .get()
        .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                     if (task.getResult() != null) {
                            List<DownloadInfo> downloadInfoList = task.getResult().toObjects(DownloadInfo.class);
                            for (DownloadInfo downloadInfo : downloadInfoList) {
                                doSomething(downloadInfo.file_name, downloadInfo.id, downloadInfo.size);
                            }
                        }
                    }
                } else {
                    Log.w(TAG, "Error getting documents.", task.getException());
                }
            }
        });

這是獲取列表的代碼。 由於這是一項異步任務,因此需要時間,這就是列表大小最初顯示為空的原因。 但是包含緩存數據的源將使先前的列表(以及它的大小)在內存中,直到執行下一個任務。

Source source = Source.CACHE;
        firebaseFirestore
                .collection("collectionname")
                .get(source)
                .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                    @Override
                    public void onSuccess(QuerySnapshot documentSnapshots) {
                        if (documentSnapshots.isEmpty()) {

                            return;
                        } else {
                            // Convert the whole Query Snapshot to a list
                            // of objects directly! No need to fetch each
                            // document.
                            List<ModelClass> types = documentSnapshots.toObjects(ModelClass.class);
                            // Add all to your list
                            mArrayList.addAll(types);
                        }

                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {

                    }
                });

假設我們有一個包含數組類型屬性的文檔。 這個數組被命名為users並且包含一些 User 對象。 User 類非常簡單,只包含兩個屬性,如下所示:

class User {
    public String name;
    public int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

這是數據庫結構:

在此處輸入圖片說明

所以我們的目標是將users數組作為List<User> 為此,我們需要在文檔上附加一個偵聽器並使用get()調用:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference applicationsRef = rootRef.collection("applications");
DocumentReference applicationIdRef = applicationsRef.document(applicationId);
applicationIdRef.get().addOnCompleteListener(task -> {
    if (task.isSuccessful()) {
        DocumentSnapshot document = task.getResult();
        if (document.exists()) {
            List<Map<String, Object>> users = (List<Map<String, Object>>) document.get("users");
        }
    }
});

為了真正從users數組中獲取值,我們調用:

document.get("users")

我們將對象轉換為List<Map<String, Object>> 所以這個對象實際上是一個地圖列表。 確實,我們可以遍歷 Map,獲取數據並自己創建List<User> 但是由於DocumentSnapshot包含不同風格的get()方法,根據每種數據類型, getString()getLong()getDate()等,如果我們也有一個getList()方法會非常有幫助,但是不幸的是,我們沒有。 所以像這樣:

List<User> users = document.getList("users");

這是不可能的。 那么我們怎樣才能得到一個List呢?

最簡單的解決方案是創建另一個僅包含List<User>類型屬性的類。 它看起來像這樣:

class UserDocument {
    public List<User> users;

    public UserDocument() {}
}

而直接獲取列表,只需要以下幾行代碼:

applicationIdRef.get().addOnCompleteListener(task -> {
    if (task.isSuccessful()) {
        DocumentSnapshot document = task.getResult();
        if (document.exists()) {
            List<User> users = document.toObject(UserDocument.class).users;
            //Use the the list
        }
    }
});

獲取自: 如何將對象數組從 Cloud Firestore 映射到對象列表?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM