在 Firestore 上存储文档:检测操作是不是在服务器上成功、本地或不成功?

Posted

技术标签:

【中文标题】在 Firestore 上存储文档:检测操作是不是在服务器上成功、本地或不成功?【英文标题】:Storing a document on Firestore: detect if the operation is successful on the server, locally or unsuccessful?在 Firestore 上存储文档:检测操作是否在服务器上成功、本地或不成功? 【发布时间】:2019-06-13 06:18:50 【问题描述】:

我正在使用 Google Firestore 编写 Java android 应用程序。当用户创建数据时,它们必须存储在 Firestore 上(用户单击“提交”按钮)。应用程序显示 ProgressBar,直到存储成功或失败。如何检测数据是否存储(本地或远程服务器上)?我想告诉用户存储成功(数据存储在服务器上),本地成功(服务器无法访问,但离线存储可以)还是不成功。

为了完成服务器上的存储,通过在 Task 上注册 OnCompleteListener 很容易检测到这一点。

但是当服务器不可达时,监听器是不会被调用的(其实是在服务器再次可达时才调用它,但是用户不能等那么久!)。我发现可以通过在 DocumentReference 上注册的 EventListener 通知数据存储在本地。此侦听器可以通过 documentSnapshot.getMetadata().isFromCache() 和 documentSnapshot.getMetadata().hasPendingWrites() 获取信息。但是当服务器在线并且数据存储在服务器上时,也会通知此侦听器。

 progressBar.setVisibility(View.VISIBLE);
 final DocumentReference documentReference =
 FirebaseFirestore.getInstance().document(documentFirestorePath);
 documentReference. addSnapshotListener(this, MetadataChanges.INCLUDE,
 new EventListener<DocumentSnapshot>() 
     @Override
     public void onEvent(@Nullable final DocumentSnapshot documentSnapshot, @Nullable final FirebaseFirestoreException e) 
         Log.i("MyActivity", "isFromCache: "+documentSnapshot.getMetadata().isFromCache()+", write pending:
 "+documentSnapshot.getMetadata().hasPendingWrites());
      );
 documentReference.set(newContact).addOnCompleteListener(new OnCompleteListener<Void>() 
     @Override
     public void onComplete(@NonNull final Task<Void> task) 
         Log.i("MyActivity", "completed");
         progressBar.setVisibility(View.INVISIBLE);
         if (task.isSuccessful()) 
             finish();
          else 
             // Inform the customer the action failed
         
     
  );

以下是服务器在线时的日志:

2019-06-13 08:11:14.126 I/MyActivity: isFromCache: true, write pending: false
2019-06-13 08:11:14.170 I/MyActivity: isFromCache: true, write pending: true
2019-06-13 08:11:14.218 I/MyActivity: isFromCache: false, write pending: true
2019-06-13 08:11:14.470 I/MyActivity: completed
2019-06-13 08:11:14.552 I/MyActivity: isFromCache: false, write pending: false

以及服务器离线时的日志:

2019-06-13 08:12:08.185 I/MyActivity: isFromCache: true, write pending: false
2019-06-13 08:12:08.215 I/MyActivity: isFromCache: true, write pending: true
And when the server is back, the following logs are added:
2019-06-13 08:12:40.460 I/MyActivity: isFromCache: false, write pending: true
2019-06-13 08:12:40.671 I/MyActivity: completed
2019-06-13 08:12:40.753 I/MyActivity: isFromCache: false, write pending: false

【问题讨论】:

【参考方案1】:

最后,告诉用户他的修改已存储(本地或服务器上)就足够了。

所以

addSnapshotListener(this, MetadataChanges.INCLUDE,
 new EventListener<DocumentSnapshot>()

足够了:检查的条件是 hasPendingWrites == true。

不需要 OnCompleteListener。

【讨论】:

以上是关于在 Firestore 上存储文档:检测操作是不是在服务器上成功、本地或不成功?的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 存储规则在 Firestore 文档上查找数据? [复制]

设置 Firestore 文档时如何检测不存在的网络连接

Firestore中的子集合在基本文档上可见吗?

无法在 Android 上使用 Cloud Firestore 保存文档

Firestore、vue、vuex、vuexfire:如何让 getter 真正从存储中获取数据?

如何在 Firestore 中一次创建/更新多个文档