Firestore的Cloud Functions:访问父集合数据

时间:2019-02-18 15:54:30

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

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

我的设置是这样的:

  
      
  • 用户      
        
    • {userid}      
          
      • last_seen:“数据”
      •   
      • {forms}      
            
        • {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


});

3 个答案:

答案 0 :(得分:3)

我完全不满意改用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;
    });
});

它还允许您为经常使用的功能分离逻辑,将其视为“帮助器”方法:(注意,我偶然切换到异步/等待,这更干净了)

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()助手...

答案 1 :(得分:2)

在您的代码中,snapDocumentSnapshot类型的对象。从链接的API文档中可以看到,该对象上有一个ref属性,您可以通过一个DocumentReference对象指向添加的文档。该对象具有parent属性,该属性为您提供一个CollectionReference,指向文档所在的集合,该集合也具有parent属性。因此,根据需要使用这些属性在数据库中导航。

答案 2 :(得分:0)

获取发生更改的参考,上移两级并使用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;

});