Firebase批处理更新和onWrite触发同步 [英] firebase batch updates and onWrite trigger synchronisation

查看:49
本文介绍了Firebase批处理更新和onWrite触发同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在同步两个Firebase云功能时遇到问题,第一个功能对多个文档执行批处理更新,第二个功能由其中一个文档的 onWrite 触发器触发.

I have an issue with synchronizing two Firebase cloud functions, the first one performing a batch update on multiple documents and the second one triggered by an onWrite trigger on one of those documents.

为说明起见,假设我有两个文档 A B (位于两个单独的集合中).

For illustration, let us say I have two documents A and B (in two separate collections).

  • 第一个云功能使用防火存储区 WriteBatch 更新了文档 A B (两个文档均已成功更新);
  • 写入文档 B 会触发另一个云功能(使用 onWrite 触发器).此功能需要读取文档 A ;
  • 我在第二个函数中有一个错误,这是因为它读取了文档 A 的旧版本(在第一个函数进行批处理之前).
  • A first cloud function updates both documents A and B with a firestore WriteBatch (both documents are successfully updated);
  • The write in document B triggers another cloud function (with an onWrite trigger). This function needs to read document A;
  • I have an error in this second function, that is because it read the old version of document A (before the write batch by the first function).

是否有办法确保 onWrite 函数仅在两个文档均已写入之后被触发?

我可以分别更新它们,并等待在第一个函数中编写 B 之前先编写 A ,但是我想在一个事务中保持两者的更新,因为这些文档是链接在一起的,我不想冒险在没有其他文档的情况下进行更新.

I could update them separately and await A to be written before I write B in the first function, but I want to keep the update of both in one transaction because these documents are linked, and I don't want to risk having one updated without the other.

推荐答案

批处理写入可确保原子写入已完成:如果一个写入失败,则不会执行其他写入.另一方面,要回答您上面的评论之一,批处理写入不能确保所有写入都是即时"的,顺便说一句,这是很难在IT恕我直言中定义的概念:-).AFAIK,批处理写入既不能保证也不会按将其推入批处理的顺序来完成写入.

A batched write ensures that the writes are atomically completed: if one write fails, the other ones are not executed. On the other hand, to answer to one of your comments above, a batched write does not ensure that all the writes will be "instantaneous", which, by the way, is a notion that is difficult to define in IT, IMHO :-). AFAIK, a batched write does not ensure neither that the writes will be done in the order they were pushed to the batch.

因此,如果要在组成批写的所有写操作都完成时触发第二个Cloud Function,则可以使用由Pub/Sub触发的Cloud Function.

So, if you want to trigger the second Cloud Function when all the writes composing the batched write are completed, you could use a Cloud Function triggered with Pub/Sub.

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

Concretely, do as follows in your index.js Cloud Functions file:

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

Declare a function that publishes a message:

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;
    }
}

在提交批处理的Cloud Function中,批处理写入完成后发布消息:

In you Cloud Function that commits the batch, publish a message when the batched write is completed:

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

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

Write a pub/sub triggered Cloud Function that executes the desired business logic. If the same business logic needs to be triggered with an onWrite trigger, share the code between the two functions

    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

如果要避免在执行批处理写入时执行 onWrite 触发的Cloud Function,则可以使用唯一的Cloud Function

If you want to avoid that the onWrite triggered Cloud Function is executed when the batched write is executed, you could flag docs A and B with the unique Cloud Function eventId via the batched write. If this flag is the same in A and B you don't execute the business logic in the onWrite triggered Cloud Function, because it will be handled by the pub.sub Cloud Function.

当然,这是基于几个假设,并且必须处理事件的流程,但这可能是一种解决方案!

Of course, this is based on several assumptions and has to cope with the flow of events but it could be a possible solution!

这篇关于Firebase批处理更新和onWrite触发同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆