Reputation: 65
I'm implementing a firestore trigger in GoLang, which will listen to changes on a collection and with, will create a new document on a different collection.
So far so good, I had a look into the official documentation here: https://cloud.google.com/functions/docs/calling/cloud-firestore#event_structure which gives an example on how we can use a custom sruct (here represented as MyData
) like so:
// FirestoreValue holds Firestore fields.
type FirestoreValue struct {
CreateTime time.Time `json:"createTime"`
// Fields is the data for this value. The type depends on the format of your
// database. Log an interface{} value and inspect the result to see a JSON
// representation of your database fields.
Fields MyData `json:"fields"`
Name string `json:"name"`
UpdateTime time.Time `json:"updateTime"`
}
// MyData represents a value from Firestore. The type definition depends on the
// format of your database.
type MyData struct {
Original struct {
StringValue string `json:"stringValue"`
} `json:"original"`
}
And that works fine. Now where it gets trickier is if our document has a number instead of a string, like:
type MyOtherData struct {
Original struct {
DoubleValue float64 `json:"doubleValue"`
} `json:"original"`
}
Everything seems fine, and in fact it works, but only if the document has a number with a decimal part, like: 1.2
. However, if this document happens to have a value without decimal part, like: 1
, then the number comes decoded to MyOtherData as 0
.
Edited:
Ok, now I get why it's 0
, because in fact, firestore doesn't distinguish between integer and float, and that makes the object coming with (in json):
"fields":{"original":{"doubleValue":3.5}
if the document has a value with a decimal part. But comes with:
"fields":{"original":{"integerValue":"3"}
if the document has no decimal part.
Does anyone knows how should this be handled elegantly? I would like to avoid using interface{} for this cases...
Thanks in advance :)
Upvotes: 1
Views: 128
Reputation: 65
So, the better option I found was to change my struct like this:
type MyOtherData struct {
Original FirestoreNumber `json:"original"`
}
type FirestoreNumber struct {
DoubleValue float64 `json:"doubleValue"`
IntegerValue int `json:"integerValue,string"`
}
func (fn *FirestoreNumber) Value() float64 {
if fn.IntegerValue != 0 {
return float64(fn.IntegerValue)
}
return fn.DoubleValue
}
Then, instead of accessing directly myOtherData.Original.DoubleValue
, I do myOtherData.Original.Value()
If someone knows a better option, please share :)
Upvotes: 1