我使用以下代码将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()将元素添加到数组中,但仅添加尚未存在的元素,这正是我想要的。

但是,问题在于,当我将一个已经存在的元素添加到数组中时,不会插入该元素,但是会调用 addOnSuccessListenerviewsCount会增加,并且永远不会调用failureListener。 有什么方法可以防止这种情况?我希望仅当将元素插入viewsCount数组时才增加views

最佳答案

但是,问题在于,当我将一个已经存在的元素添加到数组中时,不会插入该元素,但是会调用addOnSuccessListener,会增加viewsCount,而不会调用failureListener

那是正常的行为。请注意,仅当特定操作的最终结果成功时,才对数据库中执行的操作调用当前正在使用的OnSuccessListener

在您的特定情况下:

.update("views", FieldValue.arrayUnion(currentUser.getUid())

OnSuccessListener添加到uid数组的操作成功后,将调用views。那个uid是否已经存在并不重要,整个操作成功了。的确,没有将uid添加到数组中,但是即使操作成功。

还请记住,当任务所代表的工作按预期完成时,没有错误,则该任务被视为成功。另一方面,当Task发生异常失败时,将调用OnFailureListener。因此,它既可以是结果,也可以是异常,永远不能同时使用。因此,添加已经存在于数组中的uid永远不会失败。

为了解决这个问题,您应该创建一个get()调用,获取整个文档并检查uid数组中views的存在。如果不存在,请创建更新并递增计数器,否则不执行任何操作。

08-17 08:56
查看更多