GolangでFirebaseのRealtime Databaseにデータを書き込む

Go言語用のFirebase Admin SDKを使って、Realtime Databaseを操作してみる。多少公式ドキュメントのサンプルコードだと省略されている部分などがあったので、動作確認に必要な一連の流れをここにまとめておく。(2018年10月現在)

# Firebaseの準備
## 新しいプロジェクトの作成
[Firebase console](https://console.firebase.google.com/u/0/)から新しいプロジェクトを作成する。

<img width="562" alt="スクリーンショット 2018-10-21 13.59.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/14097/771a2d67-f934-16a1-faaa-466bde2af97f.png">

## 秘密鍵の生成とダウンロード
SDKからRealtime Databaseを操作するには、サービス アカウントの秘密鍵が必要となるので生成してダウンロードしておく。

プロジェクト設定を開く
<img width="425" alt="スクリーンショット 2018-10-21 14.00.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/14097/6bbb7d52-f0b9-beca-c9ba-36b51aa9d657.png">

サービス アカウントからFirebase Admin SDKの新しい秘密鍵を生成、ダウンロードする
<img width="1051" alt="スクリーンショット 2018-10-21 14.02.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/14097/cfe43d65-ed13-73ec-615d-c9b842925a65.png">

## Realtime Databaseの作成
Realtime Databaseを作成する。Cloud Firestoreはまだベータ版なので今回は従来のRealtime Databaseを選んだ。

<img width="1301" alt="スクリーンショット 2018-10-21 14.05.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/14097/c1b13271-f109-c4ff-397c-012eb7abecb9.png">

ルールを設定する。Admin SDK / サービス アカウントを使ってデータをいじる場合は、ロックモードでもOK。

<img width="705" alt="スクリーンショット 2018-10-21 19.50.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/14097/6acee332-4530-c962-fdf8-85e9c4639b50.png">

作成されたデータベースのURLをメモっておく

<img width="955" alt="スクリーンショット 2018-10-21 19.51.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/14097/9124a26f-e14b-757d-9225-7fc15f7d1612.png">

# プログラムを書く
## ライブラリのインストール
```
go get firebase.google.com/go
```

## プログラムを書く
[データの保存 | Firebase Realtime Database | Firebase](https://firebase.google.com/docs/database/admin/save-data) のサンプルコードを参考に

DatabaseURLは、適宜書き換えてください。

```go
package main

import (
	"fmt"
	"log"

	"golang.org/x/net/context"

	firebase "firebase.google.com/go"

	"google.golang.org/api/option"
)

// User is a json-serializable type.
type User struct {
	DateOfBirth string `json:"date_of_birth,omitempty"`
	FullName    string `json:"full_name,omitempty"`
	Nickname    string `json:"nickname,omitempty"`
}

func main() {
	ctx := context.Background()
	opt := option.WithCredentialsFile("fb_secret.json")
	config := &firebase.Config{DatabaseURL: "https://golang-fb-exp.firebaseio.com/"}
	app, err := firebase.NewApp(ctx, config, opt)
	if err != nil {
		panic(fmt.Sprintf("error initializing app: %v", err))
	}

	client, err := app.Database(ctx)
	if err != nil {
		log.Fatalln("Error initializing database client:", err)
	}

	// Get a database reference to our blog.
	ref := client.NewRef("server/saving-data/fireblog")

	usersRef := ref.Child("users")
	err = usersRef.Set(ctx, map[string]*User{
		"alanisawesome": {
			DateOfBirth: "June 23, 1912",
			FullName:    "Alan Turing",
		},
		"gracehop": {
			DateOfBirth: "December 9, 1906",
			FullName:    "Grace Hopper",
		},
	})
	if err != nil {
		log.Fatalln("Error setting value:", err)
	}

	log.Println("Done")
}

```

Realtime Databaseを使う場合は、`firebase.NewApp`の引数で`firebase.Config`を与え、その中で`DatabaseURL`を指定してあげる必要があることに注意。

## 認証ファイル(秘密鍵)の準備
先ほどダウンロードしてきた認証用jsonを、プログラムと同じ階層に`fb_secret.json`という名前で配置する。

## 実行+動作確認
プログラムを実行してみる。Firebase consoleのDatabase画面上でデータが追加されていることを確認できる。

<img width="952" alt="スクリーンショット 2018-10-21 23.03.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/14097/cba1a2f4-8532-51d3-b49a-273d18944fa5.png">



# 参考リンク
* [Firebase console](https://console.firebase.google.com/u/0/)
* [GitHub - firebase/firebase-admin-go: Firebase Admin Go SDK](https://github.com/firebase/firebase-admin-go)
* [The Firebase Blog: Introducing Firebase Admin SDK for Go](https://firebase.googleblog.com/2017/08/introducing-firebase-admin-sdk-for-go.html)
* [データの保存 | Firebase Realtime Database | Firebase](https://firebase.google.com/docs/database/admin/save-data)