2017-10-08 32 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上のポストを取得する過程でんだけど、ここでの抜粋です:バッチが WriteBatchクラスと書き込みに

クラウドFirestoreも素晴らしい新しい方法を含んでいます。 Androidで見つかる SharedPreferences.Editorと非常によく似ています。 インスタンスに ドキュメントを追加または更新できますが、WriteBatch#commit()に電話するまでは アプリには表示されません。私はバッチライフサイクルがあなたのために管理されている標準 コトル改善を作成しました - をcopypastaに自由に感じます。

inline fun firestoreBatch(transaction: WriteBatch.() -> Unit): Task<Void> = FirebaseFirestore.getInstance().batch().run { 
    transaction() 
    commit() 
} 
関連する問題