firebase批量更新和onWrite触发同步

Luc*_*vid 4 firebase google-cloud-platform google-cloud-functions google-cloud-firestore

我在同步两个 Firebase 云函数时遇到问题,第一个函数对多个文档执行批量更新,第二个函数由onWrite其中一个文档的触发器触发。

为了便于说明,假设我有两个文档AB(在两个单独的集合中)。

  • 第一个云功能更新文档AB使用 firestore WriteBatch(两个文档均已成功更新);
  • 写入文档B会触发另一个云功能(带有onWrite触发器)。该功能需要读取文档A
  • 我在第二个函数中出现错误,那是因为它读取了旧版本的文档A(在第一个函数进行批量写入之前)。

有没有办法确保只有在两个文档都写入后才onWrite触发该函数?

我可以单独更新它们,并在A写入第一个函数之前等待写入B,但我想将两者的更新保留在一个事务中,因为这些文档是链接的,并且我不想冒险在没有另一个的情况下更新一个文档。

Ren*_*nec 5

批量写入可确保写入以原子方式完成:如果一个写入失败,则不会执行其他写入。另一方面,为了回答您上面的评论,批量写入并不能确保所有写入都是“瞬时”的,顺便说一句,这是一个很难在 IT 中定义的概念,恕我直言:- )。AFAIK,批量写入并不能确保写入按照推送到批次的顺序完成。

因此,如果您想在组成批量写入的所有写入完成时触发第二个云函数,您可以使用通过 Pub/Sub 触发的云函数。

index.js具体来说,在您的Cloud Functions 文件中执行以下操作:

声明一个发布消息的函数:

async function publishMessage(messageConfig) {
    try {
        const pubSubClient = new PubSub();

        const topicName = messageConfig.topicName;
        const pubSubPayload = messageConfig.pubSubPayload;

        let dataBuffer = Buffer.from(JSON.stringify(pubSubPayload));
        await pubSubClient.topic(topicName).publish(dataBuffer);

    } catch (error) {
        throw error;
    }
}
Run Code Online (Sandbox Code Playgroud)

在提交批量的云函数中,当批量写入完成时发布一条消息:

    await batch.commit();
    
    messageConfig = {
          topicName: 'your-topic',
          pubSubPayload: {
              docA_Id: '..........',  // Id of doc A
              docB_Id: '..........'   // Id of doc B
          }
    }
    await publishMessage(messageConfig);
    // ...
Run Code Online (Sandbox Code Playgroud)

编写一个发布/订阅触发的云函数来执行所需的业务逻辑。如果需要用触发器触发相同的业务逻辑onWrite,两个函数之间共享代码

    exports.updateDocB = functions.pubsub.topic('your-topic').onPublish(async (message) => {

       const docA_Id = message.json.docA_Id;   
       const docB_Id = message.json.docB_Id;   

       await updateDocB(docA_Id, docB_Id);
       // ...
    
    })


    async function updateDocB(docA_Id, docB_Id)  {
       // ......
    }
    // Call this function from the onWrite CF
Run Code Online (Sandbox Code Playgroud)

如果您想避免onWrite执行批量写入时触发的云函数被执行,您可以eventId通过批量写入使用唯一的云函数标记文档A和B。如果 A 和 B 中的此标志相同,则不会在onWrite触发的云函数中执行业务逻辑,因为它将由 pub.sub 云函数处理。


当然,这是基于几个假设,并且必须应对事件的发展,但这可能是一个可能的解决方案!