Cloud Function stuck in an infinite loop

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-04 05:51:16

问题


exports.addNewValue = functions.database.ref('/path')
.onWrite(event => {    
    event.data.adminRef.update({"timeSnapshot":Date.now()})})

It appears that Date.now() causes an infinite loop in the function because the following does not:

exports.addNewValue = functions.database.ref('/path')
.onWrite(event => {    
    event.data.adminRef.update({"timeSnapshot":"newString"})})

How do I fix this?


回答1:


If you write back to the same location in the database that was previously changed, you can expect this sequence of events:

  1. Function is triggered with the first change from the client
  2. Function writes back to the database
  3. Function is triggered a second time because of the write during step #2

All writes to the database that match the filter path, even those from within the same function, will trigger the function.

In step 3, you need a strategy to figure out if the second function invocation should result in yet another write back to the database. If it does not require another write, the function should return early so that it won't trigger another write. Typically you look at the data in the event passed to the function and figure out if it was already modified the first time. This could involve looking to see if some flag is set in the database, or if the data you modified does not need any more changes.

Many of the code samples provided by the Firebase team do this. In particular, look at text moderation. Also, there is a video that describes the problem and a possible solution. In the end, you're responsible for coming up with the strategy that meets your needs.




回答2:


I think the following should work fine :-

exports.addNewValue = functions.database.ref('/path/timeSnapshot')
    .onWrite(event => {  event.data.adminRef.set(Date.now()) })

The logic behind the above is that when you put a trigger function on a higher node (such as /path in your case), then the function would be fired each time a change is made to any of its child nodes (/timestamp in your case) - hence, the infinite loop.

Therefore, as a general practice, for efficiency as well as cost effectiveness, make sure that your trigger function has the lowest possible path node. Flatting out your data really helps in this as well.




回答3:


If you arrived here having problems with querying try using .once('value') ... it will mean that you only look at the reference point once ... i.e.

ref.orderByChild("isLive").equalTo(true).once("value" , function(snapshot) {

instead of

ref.orderByChild("isLive").equalTo(true).on("value", function(snapshot) {

as the second will have you listening all the time, and when data changes at the ref, the listener will receive the changes and run the code inside your block again



来源:https://stackoverflow.com/questions/44865161/cloud-function-stuck-in-an-infinite-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!