go - 使用Go从Firestore获取单个文档的惯用方式是什么?

标签 go google-cloud-firestore firebase-admin

我正在编写一个Go服务,该服务检索具有给定ID的单个Firestore文档。实现草案如下。该代码似乎可以正常工作。 GetAccount返回map[string]interface{},它可以是nil或设置为文档数据的表示形式。go doc firestore.DocumentRef.Get显示:

func (d *DocumentRef) Get(ctx context.Context) (_ *DocumentSnapshot, err error) 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 and whose ReadTime is the time of the failed read operation.


如果DocumentSnapshot已经表明存在,那么为什么Exists()也包含status.Code(err) == codes.NotFound方法?go doc firestore.DocumentSnapshot.DataTo也说:

If the document does not exist, DataTo returns a NotFound error.


我还应该在代码路径的B点检查status.Code(err) == codes.NotFound吗?
type srv struct {
    fs *firestore.Client
}

// ...

m, err := srv.GetAccount(ctx, "81199475")
if err != nil {
    log.Fatal(err)
}
if m == nil {
    fmt.Println("NOT FOUND")
    os.Exit(0)
}
fmt.Printf("%#v\n", m)

func (s *srv) GetAccount(ctx context.Context, id string) (map[string]interface{}, error) {
    docSnap, err := s.fs.Doc("accounts/" + id).Get(ctx)
    if status.Code(err) == codes.NotFound {
        return nil, nil
    }
    if err != nil {
        return nil, err
    }

    var m map[string]interface{}
    if err := docSnap.DataTo(&m); err != nil {
        // Point B
        return nil, err
    }
    return m, nil
}
更新:已经指出,与其通过GetAccount返回nil来指示未找到文档,不如将底层Firestore错误传播到调用堆栈中,或者提供自定义错误。
var ErrAccountNotFound = errors.New("account/account-not-found")

// ...

if status.Code(err) == codes.NotFound {
    return nil, ErrAccountNotFound
}

最佳答案

您只需要检查Get返回的错误中是否找不到。DocumentSnapshot.Exists()方法对于像GetAll这样返回多个快照的方法很有用。当找不到单个文档时,这些方法不会返回错误。
使用DocumentSnapshot.Data()简化代码:

func (s *srv) GetAccount(ctx context.Context, id string) (map[string]interface{}, error) {
    docSnap, err := s.fs.Doc("accounts/" + id).Get(ctx)
    if err != nil {
        // Translate firestorm not found to application specific not found.
        if status.Code(err) == codes.NotFound {
            err = ErrAccountNotFound
        }
        return nil, err
    }
    return docSnap.Data(), nil
}

关于go - 使用Go从Firestore获取单个文档的惯用方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64806911/

相关文章:

node.js - 为每个登录用户初始化管理 Firebase 应用程序

go - 如何strings.Split换行?

go - 如何嵌入文件以供以后解析执行使用

swift Firestore 'absl/numeric/int128_have_intrinsic.inc' 文件未找到

firebase - 在 App Engine 标准 Golang 中初始化 Firebase Admin

FIrebase 部署错误 : Cannot find module 'firebase-admin'

go - 尝试将数据解码到 golang 中的界面

go - 如何同步用于并发初始化 slice 的 go 例程?

android - 为什么我的听众没有在这个 Firestore 集中点击这里

firebase 云功能 firestore 未被区域 europe-west1 触发