You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中Firestore事务报错:读取的文档必须在事务中写入

解决Firestore事务错误:Every document read in a transaction must also be written

我来帮你搞定这个头疼的问题!你遇到的这个错误是Firestore事务的核心约束导致的:事务中读取的每一个文档,必须在同一个事务内对其执行写入操作(更新、删除、设置都算)。

看你的代码,当documentSnapshot2.exists()为false时,你通过transaction.get(docRef2)读取了这个文档,但之后没有对它做任何写入操作——这直接违反了Firestore的事务规则,所以抛出了那个异常。而你移除判断条件后能成功,是因为不管文档是否存在,你都执行了删除操作(写入),满足了规则。

但你的核心需求是“只有当文档存在时才执行后续操作”,那我们可以这样调整代码,既满足业务逻辑,又符合Firestore的要求:

db.runTransaction(new Transaction.Function<Void>() {
    @Override
    public Void apply(Transaction transaction) throws FirebaseFirestoreException {
        DocumentReference docRef2 = db.collection("ABC").document(mMatchedUserId);
        DocumentReference ref3 = db.collection("XYZ").document(mCurrentUserId);
        DocumentReference ref4 = db.collection("XYZ").document(mMatchedUserId);
        
        DocumentSnapshot documentSnapshot2 = transaction.get(docRef2);
        if(documentSnapshot2.exists()) {
            // 文档存在时执行你需要的操作
            transaction.delete(docRef2);
            transaction.set(ref3, myMap1);
            transaction.set(ref4, myMap2);
        } else {
            // 文档不存在时,执行一个无意义的写入操作满足Firestore规则
            // 这里我们先设置一个空文档再删除,相当于没有修改数据库状态
            transaction.set(docRef2, new HashMap<>());
            transaction.delete(docRef2);
        }
        return null;
    }
}).addOnSuccessListener(new OnSuccessListener<Void>() {
    @Override
    public void onSuccess(Void aVoid) {
        Log.d(TAG, "Transaction success!");
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        Log.w(TAG, "Transaction failure.", e);
    }
});

为什么这么做?

当文档不存在时,我们先执行set创建一个空文档,再马上删除它——这个操作不会改变数据库的实际状态,但确实对docRef2执行了写入操作,完美满足了Firestore“读了必须写”的规则。

如果你觉得这种方式有点hack,也可以根据业务需求选择其他写入操作:比如给文档设置一个lastChecked字段为当前时间,这样既符合规则,还能记录最后检查的时间,一举两得。

内容的提问来源于stack exchange,提问作者Maverick7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:09:50