GoでFirebaseをいじいじする

Go

Firestore

▷ はじめに

Golangを使ってFirebaseをいじいじしてみたので、「こういうとこで詰まったよ〜」っていうのと、 「こんなことできたよ〜」っていうのを書いていきます📝

コードが汚かったり、変なことを言っても初心者なので許してちょんまげ!!!  

▷ Let's 下準備 📦

今回はGolang自体の環境構築自体は省略いたします。 環境構築がまだの方はこちらから

また、Firebaseのプロジェクト作成も省略いたします。 環境構築がまだの方はこちら

▼ Modulesのインストール!

まずは必要なModulesを導入していきます。 こちらのコマンドでFirebase Admin SDK を追加します。

main.go
go get firebase.google.com/go

▼ 秘密鍵の作成!

ついでに秘密鍵🔑も作成しておきましょう! 「歯車マーク > ユーザーと権限 > サービスアカウント」の順番で進んでいくと、以下のような画面になると思います。

青色の「新しい秘密鍵を作成」ボタンを押すと.jsonファイルをダウンロードできますので、それを開発ディレクトリに貼り付けましょう!

Admin SDK 構成スニペットがが必要であればGoを選択し、コピペしておきましょう!

スクリーンショット 20211107 13.19.54.png  

今回はrootにserviceAccountKey.jsonを生成し、そこに貼り付けます。 (.ignoreで非公開設定にするのを忘れないように⚠️)

今回はこんな感じのディレクトリ構成で開発をはじめました!

スクリーンショット 20211108 9.02.21.png  

▼ 初期化

ここまで来たらちゃんと導入に成功しているかをチェックします✅

今回は下記のコードでチェックしました! 何も問題なければターミナルでsuccess!!が表示されるはずです。

package main import ( "context" "fmt" firebase "firebase.google.com/go" "google.golang.org/api/option" ) func main() { ctx := context.Background() sa := option.WithCredentialsFile("serviceAccountKey.json") app, err := firebase.NewApp(ctx, nil, sa) if err != nil { fmt.Println("接続エラー。") } cilent, firestoreErr := app.Firestore(ctx) if err != nil { fmt.Println("error getting Auth client: \n", firestoreErr) } fmt.Println(client) fmt.Println("success!!") }

 

▷ 開発開始 💻

Firebaseを触るのに必要最低限の準備が(多分)できたので、早速それっぽいことをやっていきましょう😏

こちらのコードを、先ほど書いたコードの下に書くと…

// スライス(配列っぽいやつ)の宣言 var initialTechnology []string // スライス(配列っぽいやつ)に値を追加する technology := append(initialTechnology, "Next") // Firestoreにデータを追加する _, err = client.Collection("users").Doc(userInfo.ID).Set(ctx, map[string]interface{} { "id": "sampleId", "userName": "go master", "email": "go.master@exsample.com", "technology": technology, })

  何ということでしょう! こんなにも容易くFirestoreにデータを保存することができました👏

あとは自由に保存するデータ構造や値をいじったり、受け渡す値を動的にしたりなど、いろいろ楽しんでみましょう!

スクリーンショット 20211107 14.26.24.png  

▷ 詰まったところ 🚨

今回開発する上でGoが嫌いになるくらいに詰まってしまった部分を列挙しておきます。 この解決方法が正しかったかもわかりません。

動けばよかろうなのだーーーーー!  

▼ Arrayがむずかちい

私はこれまでJavaScriptしか触ってこなかったので、それ以外の言語がについての知見が皆無なのですが…

Go版「Array」みたいなのがめっちゃわかりにくいかった🥺

GoではArrayarraysliceってのに別れるっぽい。違いはわかりませんでした。

でも、ここら辺を曖昧なまま進めたことで悲劇は起きてしまいました…。  

▼ Arrayの要素数が固定だと…?

それっぽくgolang arrayって調べると当然ながらGo版「Array」が検索に引っかかるんですが、どうやら「要素数が固定的」なものらしい。

じゃあ、要素を追加したり、削除したりできないじゃんって思いました? 動的な値の時ってどうすんのよって思いました?!

僕も全くおんなじこと思いました。 しかもめっちゃエラー吐くんですよね(絶望)。

 

▼ 救世主!slice!

ということで、ここで登場するのがsliceです。

なんと宣言時に要素数を書かないだけでsliceになるらしい。

// 要素数を指定しないだけで slice になる var technology []string // 要素数を指定すると array になる var technology [3]string

 

sliceを宣言することで、要素の追加が可能になります! 要素を追加したい時はappend()を使用します。

// append()は新しいsliceを返す // JavaScriptのmap()みたいなものかな?多分 newTechnology = append(technology, 追加したい要素)

▼ 問題児!slice!

最後の問題もやはり、配列で起こってしまいました…。

Firestoreからデータを取得し、配列操作をしたいな〜と思っていた時です。

// Firestoreからデータを取得 snapshot, firestoreErr := client.Collection("users").Doc(userInfo.ID).Get(ctx) // エラーチェック if firestoreErr != nil { fmt.Println("Failed adding alovelace:", firestoreErr) } // 取得した配列に、新しい要素を追加したい…! var res = snapthot.data()["technology"] technology := append(res, "Golang") fmt.Println(technology)

 

なんと!!この書き方だと配列操作ができないというのです。

原因はresinterface{}型(空インターフェース)になってしまうことでした。  

▼ 究極奥義!型アサーション!

本来の[]string型に戻すためには型アサーションなるものを行う必要があるそうです。JSでいう型チェック的なものでしょう。多分。

ということで、オラオラ、配列になりやがれーっと型アサーション👿

res, state := snapthot.data()["technology"].([]string);

ですが、これでもうまくいきませんでした。 どんなエラーが出たかは忘れてしまいましたが、とにかくうまくいかなかったのです。

うまくいってるんならこっから先は無視してください。それはそれでバンザイ🙌  

▼ 困ったらとりあえず型変換!

このエラーに躓き、はや数時間たった深夜。 とある記事に出会うことで運命の歯車⚙が回り始めちゃいました!

FirestoreとGoのデータ型変換の関係という記事に出会い、「Firestore から Go のデータ型変換」という部分を見ると、配列(Arrays) → []interface{}と書かれてあるではありませんか…!

それに従って以下のように書き直してみると、これまでのエラーが嘘かのように動き始めました👏 ありがとう、Golang!最高だ!

// 取得した配列に、新しい要素を追加したい…! res, state := snapthot.data()["technology"].([]interface{}); technology := append(res, "Golang") fmt.Println(technology)

 

▷ おわりに

っていう感じで、初めてのサーバー言語の開発はエラーばっかりでした。 (のちにチュートリアルを見返したら、ちゃんと説明されてありました😇)

他にもたくさん詰まったところはありましたが、 何とかあってプロダクトを完成させることができました👏

せっかくなので覗いてみてください! ハックちゅう for Slack Bot

あいでん

@iden071411

目次