Reputation: 6159
I've defined a data structure like so:
type Person struct {
Name string `firestore:"name,omitempty"`
}
When I query all the documents in a collection I'd like to be able to attach the ID to the documents for later reference, but not necessarily have ID as an attribute stored in Firestore (unless its the only way). In javascript or python this is straightforward as the data structures are dynamic and I can just query the ID post get()
and add it as a dynamic key/value. myObj.id = doc.id
How would I do this with Go?
package main
import (
"fmt"
"cloud.google.com/go/firestore"
"context"
"google.golang.org/api/iterator"
"log"
)
type Person struct {
Name string `firestore:"name,omitempty"`
}
func main() {
ctx := context.Background()
c, err := firestore.NewClient(ctx, "my-project")
if err != nil {
log.Fatalf("error: %v", err)
}
var people []Person
iter := c.Collection("people").Documents(ctx)
for {
doc, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatalf("error: %v", err)
}
var p Person
err = doc.DataTo(p)
if err != nil {
log.Fatalf("error: %v", err)
}
// id := doc.Ref.ID
people = append(people, p)
}
fmt.Println(people)
}
output, no ID
>> [{John Smith}]
Upvotes: 0
Views: 977
Reputation: 115
If you want to store the firestore document ID on the Person
type, your struct must have a declared field for it.
Golang firestore docs don't mention this explicitly, but since a firestore doc ID is not part of the document fields, the func (*DocumentSnapshot) DataTo does not populate the ID. Instead, you may get the document ID from the DocumentRef type and add it to Person
yourself.
The doc also states that:
Note that this client supports struct tags beginning with "firestore:" that work like the tags of the encoding/json package, letting you rename fields, ignore them, or omit their values when empty
Therefore, if you want to omit the ID when marshaling back for firestore, your could use the tag firestore:"-"
The Person
would look like this:
type Person struct {
ID string `firestore:"-"`
Name string `firestore:"name,omitempty"`
}
inside the loop:
var p Person
err := docSnap.DataTo(&p)
if err != nil {
// handle it
}
p.ID = doc.Ref.ID
Upvotes: 1
Reputation: 12033
I believe that the firestore struct tags works the same way as the tags in the encoding/json
package. So a tag with a value of "-" would mean ignore the field.
So
type Person struct {
ID int `firestore:"-"`
Name string `firestore:"name,omitempty"`
}
should do the trick.
You can set ID yourself, but the firestore pkg will ignore it when reading/writing data.
Upvotes: 2