【问题标题】:How to get inner collection in firebase firestore如何在 Firebase Firestore 中获取内部集合
【发布时间】:2022-01-15 04:48:57
【问题描述】:

我正在尝试在 firestore 中获取特定用户的设备令牌,该设备令牌存储在“clients”或“lawyers”集合中的令牌集合中。 当我从链中删除第二个 .collection("tokens") 时,我得到了用户对象,但是使用链中的令牌集合,我似乎无法获得任何用户(客户或律师) ) 回来,即使用户和它的令牌存在。我做错了什么

  exports.onReceiveChatMessage = functions.database
  .ref("/messages/{uid}")
  .onCreate(async (snapshot, context) => {
    const newMessage = snapshot.val();
    console.log("NEW_MESSAGE", newMessage);
    const senderName = newMessage.sender_name;
    const messageContent = newMessage.content;
    console.log("SENDER'S_NAME", senderName);
    console.log("MESSAGE_BODY", messageContent);
    const uid = context.params.uid;
    console.log("RECEIVERS_ID", uid);

    if (newMessage.sender_id == uid) {
      //if sender is receiver, don't send notification
      console.log("sender is receiver, dont send notification...");
      return;
    } else if (newMessage.type === "text") {
      console.log(
        "LETS LOOK FOR THIS USER, STARTING WITH CLIENTS COLLECTION..."
      );
      let userDeviceToken;
      await firestore
        .collection("clients")
        .doc(uid)
        .collection("tokens")
        .get()
        .then(async (snapshot) => {
          if (!snapshot.exists) {
            console.log(
              "USER NOT FOUND IN CLIENTS COLLECTION, LETS CHECK LAWYERS..."
            );
            await firestore
              .collection("lawyers")
              .doc(uid)
              .collection("tokens")
              .get()
              .then((snapshot) => {
                if (!snapshot.exists) {
                  console.log(
                    "SORRY!!!, USER NOT FOUND IN LAWYERS COLLECTION EITHER"
                  );
                  return;
                } else {
                  snapshot.forEach((doc) => {
                    console.log("LAWYER_USER_TOKEN=>", doc.data());
                    userDeviceToken = doc.data().token;
                  });
                }
              });
          } else {
            snapshot.forEach((doc) => {
              console.log("CLIENT_USER_TOKEN=>", doc.data());
              userDeviceToken = doc.data().token;
            });
          }
        });
      // console.log("CLIENT_DEVICE_TOKEN", userDeviceToken);
    } else if (newMessage.type === "video_session") {
    }
     })

【问题讨论】:

    标签: node.js firebase google-cloud-firestore google-cloud-functions


    【解决方案1】:

    这一行

    if (!snapshot.exists) {

    应该是:

    if (snapshot.empty) {

    因为您在CollectionReference(返回QuerySnapshot)上调用get(),而不是在DocumentReference(返回DocumentSnapshot)上。

    如果您在示例中从链中删除 .collection('tokens'),它确实有效,因为 DocumentSnapshot 确实有成员 exists,但 CollectionReference 没有。

    在这里看看他们的成员:

    https://googleapis.dev/nodejs/firestore/latest/CollectionReference.html#get

    然后:

    https://googleapis.dev/nodejs/firestore/latest/QuerySnapshot.html

    作为建议,我过去常常混淆快照并遇到这个问题,因为使用的是 Javascript 而不是 Typescript。所以我习惯于在文档上调用结果snap,在集合上调用snaps。这让我想起了我正在做什么样的回应。像这样:

    // single document, returns a DocumentSnapshot
    const snap = await db.collection('xyz').doc('123').get();
    if (snap.exists) {
      snap.data()...
    }
    
    // multiple documents, returns a QuerySnapshot
    const snaps = await db.collection('xyz').get();
    if (!snaps.empty) { // 'if' actually not needed if iterating over docs
      snaps.forEach(...);
      // or, if you need to await, you can't use the .forEach loop, use a plain for:
      for (const snap of snaps.docs) {
        await whatever(snap);
      }
    }
    

    【讨论】:

    • 非常感谢@maganap。工作得很好。如此接近的方法有很大的不同
    • 我很高兴它有帮助。您能否将答案标记为已接受?谢谢!
    猜你喜欢
    • 2021-05-07
    • 2018-03-24
    • 2019-09-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-06
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    相关资源
    最近更新 更多