【问题标题】:Firestore collectionReference returns all documentsFirestore collectionReference 返回所有文档
【发布时间】:2020-03-30 09:26:36
【问题描述】:

我正在使用 Firebase Firestore 查询一些具有特定 ID 的文档。这是我的结构:

编辑:在此行之后添加的屏幕截图和说明:

generatedIdid 具有相同的值。我有这些“id”的列表,我想搜索public_messages 集合以返回我提供的“id”列表中的项目列表。

root
----- public_messages
---------- generatedId
-------------------- name
-------------------- id  
---------- generatedId
-------------------- name
-------------------- id  
----- other data

我正在使用以下代码查询具有特定id的消息:

 ArrayList<String> keys ... (this has some keys)

    CollectionReference collectionReference = firebaseFirestore.collection("public_messages");

    for (String id : keys) {
        collectionReference.whereEqualTo("id", id);
    }

    collectionReference.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            if (task.isSuccessful()) {
                int count = 0;
                for (QueryDocumentSnapshot document : task.getResult()) {
                    count++;
                }
                loog("total messages = " + count);
            } else {
                Log.d("TAG", "Error getting documents: ", task.getException());
            }
        }
    });

onComplete 中,变量task.getResult() 返回所述集合中的所有文档。因此,变量count 表示该集合中的文档总数。

我只想查询具有指定 ID 的结果。 id 的数量可以超过 10(这显然是 Google 设置的限制,我试图通过使用 for 循环来规避这个限制)。我该怎么办?

【问题讨论】:

  • 请编辑您的问题并将您的数据库结构添加为屏幕截图并指明您想要获得的确切过滤。
  • 添加了截图和说明。
  • 我不确定我是否完全理解它。所以你有一个 id 列表,并且你想获取与所有这些 id 对应的所有文档?这是正确的吗?
  • 是的。并且 id 的数量超过 10。或者,我正在考虑使用 DocumentReference 单独获取每条消息,但这将大大增加单个 get() 命令的数量(并且失败的风险也会增加)。所以我想制定一个解决方案,我可以一次搜索所有这些。
  • 我现在明白了。好的,我给你写一个答案。

标签: java android firebase google-cloud-firestore


【解决方案1】:

解决这个问题的关键是使用Tasks的whenAllSuccess(Collection> tasks)

当所有指定的任务成功完成时,返回一个包含任务结果列表的任务。

如以下代码行:

CollectionReference collectionReference = FirebaseFirestore.getInstance().collection("public_messages");
ArrayList<String> ids = new ArrayList<>(); //Contains your keys
ArrayList<Task<QuerySnapshot>> tasks = new ArrayList<>();
for (String id : ids) {
    Task<QuerySnapshot> task = collectionReference.whereEqualTo("id", id).get();
    tasks.add(task);
}

Tasks.whenAllSuccess(tasks).addOnSuccessListener(new OnSuccessListener<List<Object>>() {
    @Override
    public void onSuccess(List<Object> list) {
        //Do what you need to do with your list
        for (Object object : list) {
            PublicMessage publicMessage = ((DocumentSnapshot) object).toObject(PublicMessage.class);
        }
        Log.d("TAG", "Finished getting all " + list.size() + " documents");
    }
});

onSuccess() 触发时,您将确定您拥有绝对所有的文档。

【讨论】:

  • 谢谢!这是有道理的。虽然我不得不更改 for 循环代码以使用 DocumentSnapshot documentSnapshot = ((QuerySnapshot) object).getDocuments().get(0); 获取 DocumentSnapshot
【解决方案2】:

试试下面的

CollectionReference 集合参考 =

firebaseFirestore.collection("public_messages").whereIn("id", keys);

collectionReference.get().addOnCompleteListener(..);

【讨论】:

  • wherein需要列表,即使我使用列表,它也会返回所有文档
  • 您将在 ids 列表中获得所有具有您提供的 id 的文档
【解决方案3】:

试试这个:

// getting a reference to the collection
const collectionRef = collection(getFirestore(), 'COLLECTION-NAME');

//get the documents from the collection by its ref.
const querySnapshot = await getDocs(collectionRef);

// now you can run for each document with simple loop 
querySnapshot.forEach((document) => {
  console.log(document.id, ' => ', document.data());
});

【讨论】:

    猜你喜欢
    • 2022-11-30
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    相关资源
    最近更新 更多