firebase onSnapshot在创建完成之前获取更新

时间:2020-04-23 14:50:46

标签: firebase google-cloud-firestore

我有一个“帖子”,它会像这样监听react中其注释的更改:

// React hook state 
const [comments, setComments] = useState([])

// My listener in useEffect
db.collection(`users/${userId}/posts/${postId}/comments`)
   .onSnapshot((querySnapshot) => {
      let newComments = []
      querySnapshot.forEach(function (doc) {
        newComments.push({
            id: doc.id,
            ...doc.data()
        })
      })
      setComments(newComments)
   })

当用户创建新评论时,我会设置加载状态并禁用评论部分

// React hook
const [isLoading, setLoading] = useState(false)
// Add comment
const addComment = () => {
   const comment = {text:"hello"}
   setSaving(true)
   db.collection(`users/${postUid}/posts/${postId}/comments`).doc()
      .set(comment)
      .then(()=>{
         setSaving(false)
      })
}

我的问题是(要解决的一个好问题),在我的onSnapshot回调完成之前,订阅addComment得到了新的注释,这产生了一些视觉问题: -当评论输入仍在加载但评论已经存在时,使应用看起来有问题 -如果出现错误(例如:数据库权限问题),该注释将显示在列表中,然后消失...

您知道我可以更改什么才能在创建完成之前不进行onSnapshot更新吗?

1 个答案:

答案 0 :(得分:1)

如文档中的here所述:

应用程序中的本地写入将立即调用快照侦听器。 这是由于称为“延迟补偿”的重要功能。 当您执行写操作时,您的听众将收到新的通知 数据发送到后端之前。

检索到的文档具有metadata.hasPendingWrites属性,该属性可以 指示文档是否具有尚未进行的本地更改 尚未写入后端。

另请参见“收听集合中的多个文档” section中的以下备注:

如上文在本地更改事件中所述,您将收到 事件立即为您的本地写入。您的听众可以使用 每个文档上的metadata.hasPendingWrites字段,以确定是否 该文档具有尚未写入本地的更改 后端。

因此,只有在将更改写入后端时,才可以使用此属性显示更改,该更改类似于以下几行(未经测试):

db.collection(`users/${userId}/posts/${postId}/comments`)
   .onSnapshot((querySnapshot) => {
      let newComments = []
      querySnapshot.forEach(function (doc) {
        if (!doc.metadata.hasPendingWrites) {
           newComments.push({
               id: doc.id,
               ...doc.data()
           })
        }
      })
      setComments(newComments)
   })