Firebase Firestore get data from collection

时间:2017-10-12 09:47:03

标签: java android arraylist google-cloud-firestore

I want to get data from my Firebase Firestore database. I have a collection called user and every user has collection of some objects of the same type (My Java custom object). I want to fill my ArrayList with these objects when my Activity is created.

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

In onCreate():

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

Method called to get items to list:

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();
        }
    });
}

6 个答案:

答案 0 :(得分:9)

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();
                }
            });
}

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

试试这个 ..工作正常.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();

                   }
                }
        });
  

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

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

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

答案 3 :(得分:0)

这是一个简化的示例:

在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());
                }
            }
        });

答案 4 :(得分:0)

这是获取列表的代码。 由于这是一个异步任务,因此需要花费时间,这就是列表大小最初显示为空的原因。 但是,包括高速缓存数据的源将使先前的列表(及其大小)可以存储在内存中,直到执行下一个任务为止。

def LuckQuestion(questionA, questionB, questionC):
    question = input("What will you do? ").lower()
    if question in questionA:
        return 10
    elif question in questionB:
        return 4
    elif question in questionC:
        return 1

luck1 = LuckQuestion('A', 'B', 'C')
luck2 = LuckQuestion('a', 'b', 'c')
luck3 = LuckQuestion ('1', '2', '3')
luck_total = luck1 + luck2 + luck3

答案 5 :(得分:0)

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

class User {
    public String name;
    public int age;

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

这是数据库结构:

enter image description here

因此,我们的目标是将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>>。因此,该对象实际上是地图列表。的确,我们可以遍历地图,获取数据并自己创建List<User>。但是由于 DocumentSnapshot 对于get()方法包含不同的风格,根据每种数据类型 getString() getLong() getDate(),等等,如果我们也有一个getList()方法,那将非常有帮助,但是不幸的是我们没有。像这样:

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

不可能。那么我们怎么仍然可以获得列表?

最简单的解决方案是创建另一个仅包含类型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?