Firebase-云功能-对集合进行查询

时间:2018-11-13 09:58:56

标签: typescript firebase google-cloud-firestore google-cloud-functions

可以说我有两个与用户和故事有关的顶级收藏。现在,每次来自用户的文档得到更新(仅值为photoUrl{ username: 'blubber', photoUrl: 'my/photo/path', uid: 'usersUniqueId' } )时,我都希望更新故事集中的文档上的这些属性。

一个用户文档可能看起来像这样(缩短):

{
    username: 'blubber',
    photoUrl: 'my/photo/path',
    uid: 'usersUniqueId',
    sid: 'storiesUniqueId,
    content: '...'
}

故事文档可能看起来像这样(缩短):

export const onUpdateUser = functions.firestore.document('/users/{userId}')
    .onUpdate((change, context) => {
    const before = change.before.data();
    const after = change.after.data();

    if(before.username !== after.username || before.photoURL !== after.photoURL) {
        return admin.firestore().collection('/stories/')
               .where(before.uid, '==', ***fetch the comparison***)
        // do something
    } else {
        return null;
    }
});

现在在云功能部分。我现在不介绍如何从包含用户ID的故事集合中查询所有文档。现在的代码如下:

{{1}}

有人可以帮我吗?

2 个答案:

答案 0 :(得分:0)

更新了以下代码。差不多了。我添加了async await,因为它可以使代码更清晰地遵循,您需要添加错误处理等。

export const onUpdateUser = functions.firestore.document('/users/{userId}')
    .onUpdate(async (change, context) => {
    const before = change.before.data();
    const after = change.after.data();

    if (before.username !== after.username || before.photoURL !== after.photoURL) {
        return admin.firestore().collection('/stories/')
           .where('uid', '==', before.uid).get().then(  
               result => {
                   if (result.size > 0) {
                       result.forEach(async doc => {
                           await doc.ref.update({
                               username: after.username,
                               photoUrl: after.photoUrl
                           })
                        })
                   }
                   return;
               }
           )
    } else {
        return null;
    }
});

答案 1 :(得分:0)

我相信,这就是您要实现的目标。

我只是将函数调用从.onUpdate调用中的引用中分离出来。由于您没有明确声明,因此我还假设您将要更新stories集合中的多个文档,为此,我们正在使用batch

const onUpdateUser = functions
  .firestore
  .document('/users/{userID}')
  .onUpdate(myFunc);

const myFunc = (change, context) => {
  const before = change.before.data();
  const after = change.after.data();

  // Nothing changed, so exiting the cloud function early.
  if (before.username === after.username
    && before.photoURL === after.photoURL) {
    return Promise.resolve();
  }

  return admin
    .firestore()
    .collection('stories')
    .where('uid', '==', before.uid)
    .get()
    .then((docs) => {
      const batch = admin.firestore().batch();

      docs.forEach((doc) => {
        batch.set(doc.ref, {
          username: after.username,
          photoURL: after.photoURL,
        }, {
            // Merges the fields rather than replacing the 
            // whole document data
            merge: true,
        });
      });

      return batch.commit();
    })
    .catch(console.error);
};