2017-10-08 73 views
1

我使用事务在Firestore中实现了邮件喜欢和评论功能。我使用交易,因为我需要在帖子的likes/comments子集合和更新计数器中添加新字段,并且还将帖子ID添加到用户喜欢/评论的帖子集合中。Firestore runTransaction()和离线工作

我注意到,如果我下线,我要求我的文章像这样一切都OK了:

val postDocRef = FirebaseUtil.postsColRef.document(postId) 

postDocRef.get().addOnSuccessListener { doc -> 
    val post = doc.toObject(Post::class.java) 
    Timber.e(post.toString()) 
} 

但是,如果我做相同的交易异常被抛出:

val postDocRef = FirebaseUtil.postsColRef.document(postId) 

FirebaseUtil.firestore.runTransaction(Transaction.Function<Void> { transaction -> 
    val post = transaction.get(postDocRef).toObject(Post::class.java) 
} 

异常是:

com.google.firebase.firestore.FirebaseFirestoreException:UNAVAILABLE

为什么脱机模式在事务中不起作用?是否可以在离线状态下实现此功能(在子集合中添加条目并更新不同对象中的字段)?

continueWithTask()替代交易链接有什么缺点?

回答

4

不,这对于交易是不可能的,因为它们固有地依赖于网络。当您使用事务时,您告诉Firestore您只能同步执行数据库操作,一个客户端在另一个之后。交易对于诸如游戏内货币转账之类的内容非常有用,因为您需要确保不会意外地将写入数量翻倍,并为用户提供太多或太少的金钱。

如果你喜欢的计数器需要完美的精度,我会建议使用子集合,其中每个文档包含对喜欢给定帖子的用户的引用。然后,在云端功能中,您可以使用交易来计算喜欢帖子的用户数量,并确保不存在错误。如果您决定添加更多相关功能,还可以让您知道谁喜欢某个帖子,这应该是未来的证明。在客户端,即使您没有权限,也可以通过写入柜台来“欺骗”它。我没有测试过这个,但是我很确定写入会在本地成功,然后只有当你重新上线时才会失败。这并不重要,因为云端功能将同步计数器服务器端。另一方面,如果你并不真正关心拥有超精确的计数,那么你要找的是WriteBatch类。这是Firestore中的新功能,非常酷。我在获得对公司的FireStore后我写出版的过程,但这里的摘录:

云公司的FireStore还包括一个真棒新的方式批次 的WriteBatch类写道。这与您在Android上可以找到的 SharedPreferences.Editor非常相似。您可以在WriteBatch实例中添加或更新 文档,但在您拨打WriteBatch#commit()之前,您的应用将无法看到 文档。我创建了标准的 Kotlin改进,其中管理批生命周期 - 感觉 免费copypasta

inline fun firestoreBatch(transaction: WriteBatch.() -> Unit): Task<Void> = FirebaseFirestore.getInstance().batch().run { 
    transaction() 
    commit() 
}