
【第3回】Go言語(Golang)入門~Firestoreデータ操作編~
2021.12.20
第3回~Go言語(Golang)入門~

(株)ライトコードの笹川(ささがわ)です。
今回でGo言語(Golang)入門3回目!
前回に引き続き、Firestoreについて書いていきます。
今回は、データの操作をしてみよう編です!
前回の記事はこちら
データを追加してみよう
前回同様、以下ドキュメントを参考に進めたいと思います。
【データを追加する】
https://firebase.google.com/docs/firestore/quickstart?hl=ja#add_data
今回も、初期化は忘れずに入れましょう!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | package main import ( "context" "log" firebase "firebase.google.com/go" "google.golang.org/api/option" ) func main() { // 初期化 ctx := context.Background() sa := option.WithCredentialsFile("path/to/serviceAccount.json") app, err := firebase.NewApp(ctx, nil, sa) if err != nil { log.Fatalln(err) } client, err := app.Firestore(ctx) if err != nil { log.Fatalln(err) } // データ追加 _, _, err = client.Collection("users").Add(ctx, map[string]interface{}{ "first": "Ada", "last": "Lovelace", "born": 1815, }) if err != nil { log.Fatalf("Failed adding alovelace: %v", err) } // 切断 defer client.Close() } |
ドキュメントでは、各メソッドしかないのでちょっと迷いますよね!
これで実行をすると、下記のようにデータが追加されているのを確認することができます。

データ追加
さらに、別のデータも追加してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | package main import ( "context" "log" firebase "firebase.google.com/go" "google.golang.org/api/option" ) func main() { // 初期化 ctx := context.Background() sa := option.WithCredentialsFile("path/to/serviceAccount.json") app, err := firebase.NewApp(ctx, nil, sa) if err != nil { log.Fatalln(err) } client, err := app.Firestore(ctx) if err != nil { log.Fatalln(err) } // データ追加 _, _, err = client.Collection("users").Add(ctx, map[string]interface{}{ "first": "Ada", "middle": "Mathison", "last": "Lovelace", "born": 1815, }) if err != nil { log.Fatalf("Failed adding alovelace: %v", err) } // 切断 defer client.Close() } |
実行
それでは、実行してみましょう!

データがしっかりと追加されていました!
データを読みとってみよう
下記に書いてある通りに記述してみましょう。
【データを読み取る】
https://firebase.google.com/docs/firestore/quickstart?hl=ja#read_data
初期化も忘れずにやりましょう!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | package main import ( "context" "fmt" "log" firebase "firebase.google.com/go" "google.golang.org/api/iterator" "google.golang.org/api/option" ) func main() { // 初期化 ctx := context.Background() sa := option.WithCredentialsFile("path/to/serviceAccount.json") app, err := firebase.NewApp(ctx, nil, sa) if err != nil { log.Fatalln(err) } client, err := app.Firestore(ctx) if err != nil { log.Fatalln(err) } // データ読み取り iter := client.Collection("users").Documents(ctx) for { doc, err := iter.Next() if err == iterator.Done { break } if err != nil { log.Fatalf("Failed to iterate: %v", err) } fmt.Println(doc.Data()) } // 切断 defer client.Close() } |
実行
実行してみましょう!
1 2 3 | $ go run main.go map[born:1815 first:Ada last:Lovelace middle:Mathison] map[born:1815 first:Ada last:Lovelace] |
先程追加した2件のデータが読み取れています!
データを更新してみよう
こちらは、チュートリアルにないのですが、以下のドキュメントを参考にしてみました。
【Cloud Firestore にデータを追加する】
https://firebase.google.com/docs/firestore/manage-data/add-data?hl=ja
Addで追加する方法が見つからなかったので、Setで追加し、Setで更新してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | package main import ( "context" "fmt" "log" "cloud.google.com/go/firestore" firebase "firebase.google.com/go" "google.golang.org/api/iterator" "google.golang.org/api/option" ) func main() { // 初期化 ctx := context.Background() sa := option.WithCredentialsFile("path/to/serviceAccount.json") app, err := firebase.NewApp(ctx, nil, sa) if err != nil { log.Fatalln(err) } client, err := app.Firestore(ctx) if err != nil { log.Fatalln(err) } // データ追加 _, err = client.Collection("users").Doc("user2").Set(ctx, map[string]interface{}{ "first": "Ada", "middle": "Mathison", "last": "Lovelace", "born": 1815, }) if err != nil { log.Fatalf("Failed adding alovelace: %v", err) } // 切断 defer client.Close() } |
実行するとデータ追加がされます。

firstを更新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | package main import ( "context" "fmt" "log" "cloud.google.com/go/firestore" firebase "firebase.google.com/go" "google.golang.org/api/iterator" "google.golang.org/api/option" ) func main() { // 初期化 ctx := context.Background() sa := option.WithCredentialsFile("path/to/serviceAccount.json") app, err := firebase.NewApp(ctx, nil, sa) if err != nil { log.Fatalln(err) } client, err := app.Firestore(ctx) if err != nil { log.Fatalln(err) } // データ更新 _, updateError := client.Collection("users").Doc("user2").Set(ctx, map[string]interface{}{ "first": "Yeah", }, firestore.MergeAll) if updateError != nil { // Handle any errors in an appropriate way, such as returning them. log.Printf("An error has occurred: %s", err) } // 切断 defer client.Close() } |
実行
それでは、実行してみましょう!

ばっちり更新されました!
Addではなく「最初からSetをチュートリアルで書いてくれればいいのに」と思いました(笑)
データを削除してみよう
データ削除も、チュートリアルにはありません。
そのため、以下のドキュメントを参考にしたいと思います。
【Cloud Firestore からデータを削除する】
https://firebase.google.com/docs/firestore/manage-data/delete-data?hl=ja
フィールドの削除
では、まずフィールドの削除をしてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | package main import ( "context" "fmt" "log" "cloud.google.com/go/firestore" firebase "firebase.google.com/go" "google.golang.org/api/iterator" "google.golang.org/api/option" ) func main() { // 初期化 ctx := context.Background() sa := option.WithCredentialsFile("path/to/serviceAccount.json") app, err := firebase.NewApp(ctx, nil, sa) if err != nil { log.Fatalln(err) } client, err := app.Firestore(ctx) if err != nil { log.Fatalln(err) } // フィールド削除 _, errorDelete := client.Collection("users").Doc("user2").Update(ctx, []firestore.Update{ { Path: "middle", Value: firestore.Delete, }, }) if errorDelete != nil { // Handle any errors in an appropriate way, such as returning them. log.Printf("An error has occurred: %s", err) } // 切断 defer client.Close() } |
実行
実行してエラーがでなければ、成功です。
では、実際にデータを見てみましょう!

「middle」が消えていますね!
user2を削除してみる
このまま、この「user2」を削除してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | package main import ( "context" "fmt" "log" "cloud.google.com/go/firestore" firebase "firebase.google.com/go" "google.golang.org/api/iterator" "google.golang.org/api/option" ) func main() { // 初期化 ctx := context.Background() sa := option.WithCredentialsFile("path/to/serviceAccount.json") app, err := firebase.NewApp(ctx, nil, sa) if err != nil { log.Fatalln(err) } client, err := app.Firestore(ctx) if err != nil { log.Fatalln(err) } // ドキュメント削除 _, errorDelete := client.Collection("users").Doc("uesr2").Delete(ctx) if errorDelete != nil { // Handle any errors in an appropriate way, such as returning them. log.Printf("An error has occurred: %s", err) } // 切断 defer client.Close() } |
エラーが出ないので成功です!
しかし、コンソール上だとデータが消えていません!

下記ドキュメントだとこのように書かれています。
【Cloud Firestore からデータを削除する】
https://firebase.google.com/docs/firestore/manage-data/delete-data?hl=ja
警告: ドキュメントを削除しても、そのドキュメントのサブコレクションは削除されません。
ドキュメントを削除しても、Cloud Firestore はサブコレクション内のドキュメントを自動的には削除しません。サブコレクションのドキュメントには参照により引き続きアクセスできます。たとえば、パス /mycoll/mydoc/mysubcoll/mysubdoc にあるドキュメントには、/mycoll/mydoc の祖先ドキュメントを削除してもアクセスできます。
存在しない祖先ドキュメントはコンソールには表示されますが、クエリの結果やスナップショットには表示されません。
ドキュメントと、そのドキュメントのサブコレクション内のすべてのドキュメントを削除するには、手動での操作が必要です。詳しくは、コレクションを削除するをご覧ください。
手動で削除が必要ならば、なぜこの処理が用意されているんでしょうか...?
コレクションの削除
次は、コレクションの削除をしてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | package main import ( "context" "fmt" "log" "cloud.google.com/go/firestore" firebase "firebase.google.com/go" "google.golang.org/api/iterator" "google.golang.org/api/option" ) func main() { // 初期化 ctx := context.Background() sa := option.WithCredentialsFile("path/to/serviceAccount.json") app, err := firebase.NewApp(ctx, nil, sa) if err != nil { log.Fatalln(err) } client, err := app.Firestore(ctx) if err != nil { log.Fatalln(err) } ref := client.Collection("users") deleteCollection(ctx, client, ref, 10) } func deleteCollection(ctx context.Context, client *firestore.Client, ref *firestore.CollectionRef, batchSize int) error { for { // Get a batch of documents iter := ref.Limit(batchSize).Documents(ctx) numDeleted := 0 // Iterate through the documents, adding // a delete operation for each one to a // WriteBatch. batch := client.Batch() for { doc, err := iter.Next() if err == iterator.Done { break } if err != nil { return err } batch.Delete(doc.Ref) numDeleted++ } // If there are no documents to delete, // the process is over. if numDeleted == 0 { return nil } _, err := batch.Commit(ctx) if err != nil { return err } } } |
こちらは、エラーハンドリングを端折ってしまったので、ビルド時にエラーが出なければ、そのまま実行で問題ありません。

「uesrs」というidは、消えないようです。
確かに処理の内容としては、usersのドキュメントとコレクションを「for」で消していくという処理ですのでこうなりますね。
データ削除については、なんだか弱い気がしました。
第4回へつづく!
データの操作について、いろいろ試してみました。
今回は、Go言語(Golang)より、Firestoreの使い方のほうにつまずいた印象がありました。
データの扱いは「追加」「読み取り」「更新」「削除」をやれないと意味ないですからね!
今回、作成したgoファイルはこちらのリポジトリにて管理しています。
次回の記事はこちら
オススメのGo入門本
こちらの記事もオススメ!
第1回の記事はこちら
書いた人はこんな人

- 新潟生まれ新潟育ち本業はモバイルアプリエンジニア。
日々、猫(犬)エンジニアとして活躍中!
IT技術9月 20, 2023開発効率を少しだけ上げるGithubActionsの便利な使い方
IT技術4月 7, 2023【ISUCON部】ライトコードISUCON部 始動!
IT技術4月 18, 2022【Android】Webでよくみる入力Boxを手作り
IT技術1月 19, 2022【Android】SeekbarでスイッチなUIを作る