问题
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:
- Function is triggered with the first change from the client
- Function writes back to the database
- 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