有没有一种简单的方法可以将protojson格式的Firestore数据解组到map[string]interface{}或struct中,而不需要所有的protobuf数据类型标签?例如,将protojson数据扁平化。
我有一个Google cloud函数,每当创建一个新的Firebase文档时就会触发(一个“云事件”)。这个云事件包括上下文信息,包括以protojson格式修改的文档:
import (
"google.golang.org/protobuf/encoding/protojson"
"github.com/davecgh/go-spew/spew"
)
func CloudFunction(ctx context.Context, e event.Event) error {
data := firestoredata.DocumentEventData{}
_ = protojson.Unmarshal(e.DataEncoded, &data);
spew.Dump(data)
}
--------Console Output--------
{
"oldValue": {},
"value": {
"createTime": "2023-03-30T00:00:00.000000Z",
"updateTime": "2023-03-30T00:00:00.000000Z",
"name": "projects/myproject/databases/(default)/documents/collectionname/00000000-0000-0000-0000-000000000000",
"fields": {
"ID": {
"stringValue": "00000000-0000-0000-0000-000000000000"
},
"action": {
"stringValue": "serverDoSomething"
},
"payload": {
"mapValue": {
"fields": {
"questionsList": {
"arrayValue": {
"values": [
{
"mapValue": {
"fields": {
"title": {
"stringValue": "How do I fly a kite?"
},
}
}
},
{
"mapValue": {
"fields": {
"title": {
"stringValue": "How do I fly a plane?"
},
}
}
}
]
}
}
}
}
}
}
},
"updateMask": {}
}
我想将这个protojson文档的块编组到自定义的Go结构中,以轻松地验证每种类型的条目,如下所示:
// CloudEventRequest is a struct that wraps around one or more data validation structs contained in the payload
CloudEventRequest {
ID: "00000000-0000-0000-0000-000000000000"
Action: "serverDoStuff"
Payload: map{
"questionsList": []Question{
Question{
Title: "How do I fly a kite?"
},
Question{
Title: "How do I fly a plane?"
}
}
}
}
Firestore SDK包含一个DataTo方法,可以轻松地将protojson格式的数据解组到自定义结构中。我正在尝试做一些非常类似的事情,但已经从Firestore SDK外部获得了文档数据。
// DataTo uses the document's fields to populate p, which can be a pointer to a map[string]interface{} or a pointer to a struct.
func (*firestore.DocumentSnapshot).DataTo(p interface{}) error
import (
"context"
"cloud.google.com/go/firestore"
)
func FirestoreRead(docEvent firestoredata.DocumentEventData) error {
ctx := context.Background()
ref := h.client.Collection("mycollection").Doc(docEvent.value.ID)
docSnapshot, err := tx.Get(ref)
dataValidationStruct := CloudEventRequest{}
err = docSnapshot.DataTo(&dataValidationStruct)
}
1条答案
按热度按时间9njqaruj1#
我写了一个开源的Go包,名为“firestruct”来解决这个挑战。你可以在这里找到它:github.com/bennovw/firestruct欢迎您的反馈或贡献!
最后,我编写了一个函数,递归地将Firestore字段解包为匹配的map,然后重构了cloud.google.com/go/firestore中的DataTo()方法,将map解包为一个结构体。