Firebase Firestore 从集合中获取数据

Firebase Firestore get data from collection

我想从我的 Firebase Firestore 数据库中获取数据。我有一个名为用户的集合,每个用户都有一些相同类型的对象的集合(我的 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()操作returns一个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();
                }
            });
}

试试这个..工作 fine.Below 功能也将从 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();

                   }
                }
        });

More reference :https://firebase.google.com/docs/firestore/query-data/listen

如果您不想实时更新,请参阅下面的文档

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

这是一个简化的例子:

在 Firebase 中创建一个集合 "DownloadInfo"。

并添加一些包含这些字段的文档:

file_name(字符串), 编号(字符串), 尺寸(数量)

创建您的class:

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) {

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

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

假设我们有一个包含 属性 类型数组的文档。该数组名为 users 并包含一些 User 对象。 User class 非常简单,只包含两个属性,如下所示:

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");

不可能。那么我们怎样才能得到一个列表呢?

最简单的解决方案是创建另一个 class,它仅包含类型 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
        }
    }
});

获取自:How to map an array of objects from Cloud Firestore to a List of objects?