繁体   English   中英

Firestore 查询,其中结果有一个字段,该字段包含要传递给第二个查询以检索所有文档的文档引用

[英]Firestore query where the results have a field that contains a document ref to be passed to a second query to retrieve all the documents

我有一个数据库结构尝试处理经典事件/参与者模式。 我有参与者的活动,参与者参加活动。 我相信对于提供参与者参加的所有事件的详细信息以正确扩展的查询,查询所有事件并过滤它们以找到参与者并不是一个好习惯。 欢迎对此观点发表评论。 用户在一个集合中,事件在另一个集合中。 所以我向用户添加了一个 subEvent 子集合来存储他们参与的事件的文档引用。我现在想从用户的查询中检索这些文档引用,并在事件的第二个查询中检索详细的事件记录。 这是两者中都有事件ID的方案。

在此处输入图像描述

在此处输入图像描述

我的第一个查询如下所示:-

const asnapshot = await db.collection("users").doc(_req.params.id).collection("subEvents").get();

第二个:-

const doc = await db.collection("events").doc(results_from_asnapshot).get();

其中results_from_asnapshot只是第一个文档 ID 的占位符。 注意我的意思是 ids 复数,因为第一个查询将返回多个结果,而第二个只返回一个。 为了解决这个问题,我尝试从包含所有事件的快照创建一个结果,然后在第二个查询中循环它们以构建参与者参加的事件的完整详细列表。 出现了几个问题,我希望得到帮助。 一个是第一个查询中的 output 在第二个查询中是可以接受的,对于将看到的内容似乎存在冲突的答案。 有人说这样的字符串会起作用,而其他人则不会。 我有doc.data() is not a function错误一直困扰着我,直到无缘无故地在这样的测试查询中它莫名其妙地消失了。

const doc = await db.collection("events").doc("0adFOpcHZZONGDu3Qw7n").get();

其次如何正确循环第二个查询。 第三个问题是为什么前面有 await 的第二个查询会在 linter 中警告 await 将被忽略。 我知道一个查询必须在下一个查询开始之前结束,所以为什么不使用等待呢? 这是我有很大缺陷的尝试,我尝试过的数百次尝试之一,你会注意到它是 node.js firebase function:

const functions = require("firebase-functions");
const express = require("express");

const admin = require("firebase-admin");
admin.initializeApp();

const appWhen = express();
const db = admin.firestore();

appWhen.get("/eventsDetails/:id", async (_req, res) => {
  functions.logger.log("Function started");

const snapshot = await db.collection("users").
doc(_req.params.id).collection("subEvents").get();

const userevents = [];
snapshot.forEach((doc) => {
const id = doc.id;
const data = doc.data().eventID; 
userevents.push({id, ...data});
});
functions.logger.log("userevents", JSON.stringify(userevents));//EDIt Clearer log
const eventlist = [];
userevents.forEach((event) => {
 const doc = db.collection("events").doc(event).get();// Edit removed await
 const id = doc.id;
 const eventData = doc.data();
 functions.logger.log("eventData", eventData);
 eventlist.push({id, ...eventData});
 });
res.status(200).send(JSON.stringify({id: id, ...eventlist}));
});

欢迎任何帮助。

我会指出您的代码存在一些问题。

  1. 如果要按顺序阅读文档,确实不能使用 forEach。 只需使用现代for … of循环,其中 await 将按预期工作:

     for (const event of userevents) {... }
  2. 如果您使用结果中的引用字段,则只需执行引用并获取数据。

     const doc = await event.eventID.get();
  3. 在这行代码上: res.status(200).send(JSON.stringify({id: id, ...eventlist})); ,我不确定你从哪里得到变量 id,因为所有变量id都在一个循环中,你会得到一个错误。


这是一个示例工作片段供您参考:

const functions = require("firebase-functions");
const express = require("express");

const admin = require("firebase-admin");
admin.initializeApp();

const appWhen = express();
const db = admin.firestore();

appWhen.get("/eventsDetails/:id", async (_req, res) => {
  
  functions.logger.log("Function started");

  const snapshot = await db.collection("users").doc(_req.params.id).collection("subEvents").get();

  const userevents = [];

  snapshot.forEach((doc) => {
    const id = doc.id;
    const data = doc.data().eventID; 
    userevents.push({id, ...data});
  });

  functions.logger.log("userevents", JSON.stringify(userevents));
  
  const eventlist = [];
  // In here, you can see that I didn't use `.foreach`.
  // `await` will not work using `.foreach`
  // If you want to use `.foreach`, you have to use the Promise `.then` instead.
  for (const event of userevents) {
    // Use the reference and use `get()` to fetch the data.
    const doc = await event.eventId.get();
      if (doc.exists) {
        const id = doc.id;
        const eventData = doc.data();
        eventlist.push({id, ...eventData});
      } else {
        // doc.data() will be undefined in this case
        console.log("No such document!");
      }
  }
  // In here, I'm not sure what ID you want to use as you haven't declared the variable `id` globally
  // So using the variable ID will return an error.
  res.status(200).send(JSON.stringify({id: ??, ...eventlist}));
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM