【问题标题】:Cloud Functions for Firestore: accessing parent collection dataCloud Functions for Firestore:访问父集合数据
【发布时间】:2019-07-12 01:22:24
【问题描述】:

许多博客建议切换到 Cloud Firestore,因为它既简单又安全。来自实时数据库并在使用 Functions + RD 时返回,可以轻松浏览文档触发器,例如 ref.parent

我的设置是这样的:

  • 用户
    • {用户名}
      • last_seen:“数据”
      • {表格}
        • {formid}

但是,我添加了一个带有onCreate 的文档触发器,我想获取last_seen 的值:

exports.updateUser = functions.firestore.document('users/{userId}/forms/{formid}').onCreate((snap, context) => {

    const newValue = snap.data();
    console.log("test value : " + newValue.test); // works
    console.log("form id: " + context.params.formid); // works
    console.log("user last seen : " + newValue.last_seen); // doesn't work, can't access the parent collection data


});

【问题讨论】:

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


    【解决方案1】:

    我完全对切换到 Firestore 感到困惑,但在这种情况下几乎完全相同。

    实时,你有快照:

    exports.doStuff = functions.database.ref('/users/{userId}/forms/{formId}')
        .onCreate((snapshot, context) => {
        const ref = snapshot.ref;
        const userRef = ref.parent.parent;
        userRef.once('value').then(parentSnap => {
            const user = parentSnap.val();
            const lastSeen = user.last_seen;
        });
    });
    

    在 Firestore 中:

    exports.doStuff = functions.firestore.document.onCreate('/users/{userId}/forms/{formId}')
        .onCreate((snapshot, context) => {
        const ref = snapshot.ref;
        const userRef = ref.parent.parent;
        userRef.get().then(parentSnap => {
            const user = parentSnap.data();
            const lastSeen = user.last_seen;
        });
    });
    

    要考虑的另一件事是您在参数中传递了userId,这样您就可以构建自己的 DocumentReference(假设您也在使用 firebaseAdmin)

    functions.firestore.document.onCreate('/users/{userId}/forms/{formId}')
        .onCreate((snapshot, context) => {
        const userId = context.params.userId;
        const userRef = firebaseAdmin.firestore().collection('users').doc(userId);
        userRef.get().then(parentSnap => {
            const user = parentSnap.data();
            const lastSeen = user.last_seen;
        });
    });
    

    它还允许您为可能经常使用的函数解耦逻辑,将其视为“帮助”方法:(注意,我意外切换到 async/await,它更简洁)

    functions.firestore.document.onCreate('/users/{userId}/forms/{formId}')
        .onCreate(async (snapshot, context) => {
        const userId = context.params.userId;
        const lastSeen = await getLastSeen(userId);
    });
    
    // == Helper Functions ==-------------------
    export async getLastSeen(userId) {
        if (!userId) return Promise.reject('no userId');
        // User Ref
        const userSnap = await firebaseAdmin.firestore().collection('users').doc(userId).get();
        return userSnap.data().last_seen;
    }
    

    现在您可以在需要时使用getLastSeen(),如果您进行更改,您只需调整该功能。如果这不是您经常调用的东西,请不要担心,但我可能会考虑使用 getUser() 助手...

    【讨论】:

    • 如此干净简洁的答案,非常感谢您的提示
    【解决方案2】:

    在您的代码中,snap 是一个 DocumentSnapshot 类型的对象。正如您从链接的 API 文档中看到的那样,该对象上有一个 ref 属性,它可以让您获得一个指向已添加文档的 DocumentReference 对象。该对象具有parent 属性,它为您提供了一个CollectionReference,它指向文档所在的集合,该集合也有一个parent 属性。因此,请根据需要使用这些属性在您的数据库中导航。

    【讨论】:

      【解决方案3】:

      获取发生更改的参考,向上移动 2 个级别并使用 ref.once() 函数捕获数据:

      exports.updateUser = functions.firestore.document('users/{userId}/forms/{formid}').onCreate( async (snap, context) => {
      
          // Get the reference where the change took place
          const changeRef = snap.after.ref;
      
          // Move to grandad level (2 levels up)
          const userIdRef = changeRef.parent.parent;
      
          // Capture data
          const snapshot = await userIdRef.once('value');
      
          // Get variable
          const lastSeen = snapshot.val().last_seen;
      
          // Do your stuff...
      
          return null;
      
      });
      

      【讨论】:

        猜你喜欢
        • 2019-08-18
        • 2017-09-24
        • 1970-01-01
        • 2018-04-24
        • 2020-02-01
        • 2018-09-15
        • 1970-01-01
        • 2020-05-20
        • 2023-03-11
        相关资源
        最近更新 更多