值侦听器上的Firebase偶尔会触发两次,并且第二次调用不应将其值设为null

时间:2018-08-18 01:02:05

标签: javascript firebase firebase-realtime-database

基于值侦听器的Firebase有时会触发两次,回调的第一次调用具有它在数据库中的实际值,但偶尔还会有第二次调用,该调用无缘无故地为空值。

我已经通过一些技巧解决了这个问题,但是我只是想知道这是否是预期的Firebase行为,或者我发生了一些错误。

//threshold value is set dynamicly depending on another query
queryNewPosts = postRef.orderByKey().startAt(threshold)
listenerNewItems = queryNewItems.on("child_added", function(snapshot){

    let postRef = db.ref(`items/${place}/${snapshot.key}`)
    postRef.on("value", function(postSnap){
        //!!This sometimes fires twice and postSnap.val() == null
        //postSnap.val() is null when its path has a value in the database
    })
})

包括两次根据请求对数据库进行写的情况

//client side
let postsRef = db.ref(`items/${place}`)
let postKey = postsRef.push().key

postsRef.child(postKey).set({
  id: postKey,
  timestamp: firebase.database.ServerValue.TIMESTAMP,
  content: post.content.toLowerCase(),
  user: uid,
  commentCount: 0,
  vote: 0
})

云函数代码,可能是空写发生的地方

如果postId以某种方式最终为空,则事务可能会将null写入错误的路径

exports.updatePostVote = functions.database
.ref('/postVotes/{place}/{postId}/{uid}').onWrite((change, context) =>{

  if (change.before.exists() && !change.after.exists())
     return null;

  let afterValue = change.after.val()
  let beforeValue = change.before.val()

  if (afterValue === beforeValue)
    return null;

  const postId = context.params.postId
  const place = context.params.place
  const uid = context.params.uid
  const dif = afterValue - (beforeValue || 0)

  const ref = admin.database().ref(`/posts/${university}/${postId}`)

  return ref.child('vote').transaction(function(current) {
    return (current || 0) + dif;
  });
});

0 个答案:

没有答案