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

Go操作Firestore判断文档是否存在时触发NotFound错误如何处理

问题结论

你的调整方向完全正确,仅需要补充错误类型判断逻辑即可,你当前写的二次doc.Exists()判断属于冗余逻辑,且存在逻辑隐患。


原理说明

根据Firestore官方Get()方法的定义:

Get retrieves the document. If the document does not exist, Get return a NotFound error, which can be checked with status.Code(err) == codes.NotFound;In that case, Get returns a non-nil DocumentSnapshot whose Exists method return false.

对应行为规则如下:

  • 文档存在时,Get()返回nil错误,返回的DocumentSnapshot的Exists()固定为true
  • 文档不存在时,Get()同时返回NotFound错误和非空的DocumentSnapshot,此时快照的Exists()返回false
  • 其他错误场景(网络异常、权限不足等)会返回对应错误,无有效快照返回

你最初的代码没有区分错误类型,直接把所有错误返回,才会走不到后续的存在性判断分支。


现有调整代码的问题

  1. 缺失必要依赖导入:需要额外导入两个gRPC相关包才能使用status和codes判断错误类型:
import (
    "google.golang.org/grpc/codes"
    "google.golang.org/grpc/status"
)
  1. 二次判断逻辑冗余且错误:
  • 如果Get()没有返回错误,说明文档一定存在,doc.Exists()必然返回true,不需要额外判断
  • 你在NotFound分支处理完写入逻辑后没有跳出,会继续走到后续的doc.Exists()判断,但此时的doc是之前Get()返回的不存在的快照,会导致判断逻辑不符合预期

优化后正确实现

package main

import (
    "context"
    "errors"
    "log"

    "cloud.google.com/go/firestore"
    "google.golang.org/grpc/codes"
    "google.golang.org/grpc/status"
)

func main() {
    ctx := context.Background()
    client, err := firestore.NewClient(ctx, "PROJECTID")
    if err != nil {
        log.Fatalln(err)
    }
    defer client.Close()

    docRef := client.Collection("claimed").Doc("123abc")
    doc, err := docRef.Get(ctx)
    if err != nil {
        // 非文档不存在的错误直接抛出
        if status.Code(err) != codes.NotFound {
            log.Fatalln(err)
        }
        // 文档不存在,执行写入逻辑
        _, err = docRef.Set(ctx, /* 此处替换为自定义对象 */)
        if err != nil {
            log.Fatalln(err)
        }
        return
    }

    // 走到此处说明文档已存在,直接处理存在逻辑即可
    log.Fatalln(errors.New("document ID already exists"))
}

补充提示

如果你的业务场景存在并发写入的可能,建议将整个判断+写入逻辑放到Firestore事务中执行,避免出现两个请求同时判定文档不存在、重复写入的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:54:04