2017-10-08 114 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() 
}