Series:
go-firestore
Go で Cloud Firestore を使ってみる2
Cloud Firestore へのデータ書き込みなど。
前回 の続き。
コードは下記に纏めてアップした。
https://gitlab.com/k1350/daybreak_sample/-/tree/firebase_sample/
今回やった部分のみかいつまんで書いていく。
フォームから受け取った値を Firebase に書き込む
type Content struct {
Text string `firestore:"text,omitempty"`
Created time.Time `firestore:"created,omitempty"`
Updated time.Time `firestore:"updated,omitempty"`
}
このように Firestore 上のフィールド名を指定した構造体を作って
err := r.ParseForm()
if err != nil {
log.Fatalln(err)
}
c := Content{
Text: r.Form.Get("text"),
Created: time.Now().UTC(),
Updated: time.Now().UTC(),
}
_, _, err = client.Collection("posts").Add(ctx, c)
if err != nil {
log.Fatalln("An error has occurred: %s", err)
}
このようにすると ID は自動採番でデータを追加できる。(データは http/template で作った画面からフォームで受け取っている前提)
時刻については常に特定のタイムゾーンで処理するほうがいいと思うので UTC で追加した。
データ読み込み時のオーダー指定
下記のようにすると created 降順で 10 件取れる。
iter := client.Collection("posts").OrderBy("created", firestore.Desc).Limit(10).Documents(ctx)
ページングについてはまだやっていないが、こんな感じでクエリを作って取得するのは変わりないはず。
データ読み込み時のタイムゾーンについて
常に UTC でデータが取得できるのでこっちでタイムゾーンを変える。
本当はブラウザのタイムゾーンで書き換えるようなことをしたかったが、とりあえずサーバーサイドで JST に変えてみる。
time.Local = time.FixedZone("Local", 9*60*60)
jst, _ = time.LoadLocation("Local")
iter := client.Collection("posts").OrderBy("created", firestore.Desc).Limit(limit).Documents(ctx)
var posts []map[string]interface{}
for {
doc, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatalln("Failed to iterate: %v", err)
}
item := doc.Data()
v := make(map[string]interface{})
v["text"] = item["text"]
v["created"] = item["created"].(time.Time).In(jst)
v["updated"] = item["updated"].(time.Time).In(jst)
posts = append(posts, v)
}
こんな感じで取得した doc.Data() の時刻データを time.Time にキャストした上でを JST に変えて別の Map に格納しなおしてみた。もっとすっきりした書き方があるような気もする。
以上