使用结构(或protobuf消息)作为数据更新Golang中的Firestore文档 [英] Updating Firestore documents in Golang using structs (or protobuf messages) as data

查看:80
本文介绍了使用结构(或protobuf消息)作为数据更新Golang中的Firestore文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用以下API:

syntax = "proto3";

service FooService {
  rpc UpdateFoo(UpdateFooRequest) returns (Foo) {}
}

message Foo {
  string name = 1;
  string description = 2;
  string action = 3;
}

message UpdateFooRequest {
  Foo foo = 1;
  // The list of fields to be updated. For the `FieldMask` definition,
  // see https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask
  google.protobuf.FieldMask update_mask = 2;
}

此API与后端Firestore的"foos"对话.收藏.
该实现在Golang中. firestore 有一个 Update()方法,但是它需要提供一个 firestore.Update 结构的列表:

This API talks to a backend Firestore "foos" collection.
The implementation is in Golang. The firestore package has an Update() method, but it requires to provide a list of firestore.Update structs:

type Update struct {
    Path      string // Will be split on dots, and must not contain any of "˜*/[]".
    FieldPath FieldPath
    Value     interface{}
}

我在编写RPC UpdateFoo 的实现时遇到问题:我无法轻松构造 firestore.Update 结构.同时,我想确保 update_mask 中提供的路径有效.

I have problems writing the implementation of the RPC UpdateFoo: I cannot easily construct the firestore.Update struct. At the same time, I want to ensure that the paths provided in the update_mask are valid.

这是我正在尝试的:

func (s *Server) UpdateFoo(ctx context.Context, req *pb.UpdateFooRequest) (*pb.Foo, error) {

var updates []firestore.Update
// Loop all paths in the update_mask
for _, p := range req.GetUpdateMask().GetPaths() {
   // Check that path is valid field of Foo message.
   // How to do this?
   ...
   ...
   if path is not valid {
       return nil, status.Errorf(codes.InvalidArgument, "invalid path %s", p)
   }
   // When path is valid, I need to take the value from the req.GetFoo() message
   // How to do this?
   newValue := req.GetFoo().Get????<this is p variable>

   update = append(update, &firestore.Update{Path: p, Value: newValue}
}

任何提示将不胜感激.

推荐答案

我在Golang中尝试将Firestore与protobuf一起使用时遇到了类似的问题.似乎不支持使用原型场掩码和结构进行更新.

I ran into a similar issue trying to use firestore along with protobuf in Golang. There does not seem to be support for using proto field masks and structs to do updates.

这是使用 Set fieldmask-utils 的一种解决方法:

Here's a workaround with Set and fieldmask-utils:

import (
  "github.com/golang/protobuf/protoc-gen-go/generator"
  fieldmask_utils "github.com/mennanov/fieldmask-utils"
)

var (
  id      string
  request UpdateFooRequest
)

mask, err: = fieldmask_utils.MaskFromProtoFieldMask(request.FieldMask, generator.CamelCase)
// handle err...

m := make(map[string]interface{}) // a map to copy to
err := fieldmask_utils.StructToMap(mask, request.Foo, m)
// handle err..

_, err = r.client.Collection(r.collection).Doc(id).Set(ctx, m, firestore.MergeAll)
// handle err..

这篇关于使用结构(或protobuf消息)作为数据更新Golang中的Firestore文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆