我使用以下代码将userId添加到Cloud Firestore文档中的数组:
DocumentReference reference = firebaseFirestore.collection("photos").document(photoId);
reference.update("views", FieldValue.arrayUnion(currentUser.getUid()))
.addOnSuccessListener(new OnSuccessListener<Void>()
{
@Override
public void onSuccess(Void aVoid)
{
reference.update("viewsCount", FieldValue.increment(1));
}
});
从代码中可以看到,仅当元素添加到
viewsCount
数组中时,我才希望views
递增。根据此Adding Data文档,
arrayUnion()
将元素添加到数组中,但仅添加尚未存在的元素,这正是我想要的。但是,问题在于,当我将一个已经存在的元素添加到数组中时,不会插入该元素,但是会调用
addOnSuccessListener
,viewsCount
会增加,并且永远不会调用failureListener。 有什么方法可以防止这种情况?我希望仅当将元素插入viewsCount
数组时才增加views
。 最佳答案
但是,问题在于,当我将一个已经存在的元素添加到数组中时,不会插入该元素,但是会调用addOnSuccessListener
,会增加viewsCount,而不会调用failureListener
。
那是正常的行为。请注意,仅当特定操作的最终结果成功时,才对数据库中执行的操作调用当前正在使用的OnSuccessListener
。
在您的特定情况下:
.update("views", FieldValue.arrayUnion(currentUser.getUid())
将
OnSuccessListener
添加到uid
数组的操作成功后,将调用views
。那个uid
是否已经存在并不重要,整个操作成功了。的确,没有将uid
添加到数组中,但是即使操作成功。还请记住,当任务所代表的工作按预期完成时,没有错误,则该任务被视为成功。另一方面,当Task发生异常失败时,将调用
OnFailureListener
。因此,它既可以是结果,也可以是异常,永远不能同时使用。因此,添加已经存在于数组中的uid
永远不会失败。为了解决这个问题,您应该创建一个
get()
调用,获取整个文档并检查uid
数组中views
的存在。如果不存在,请创建更新并递增计数器,否则不执行任何操作。