GoとFirestore(データ登録)

# はじめに
GoとFirestoreを少し触ったのでそこで得た知識をわすれないよに書きます

とりあえずデータ登録に関して....

# secret.json

データを登録、取得する際にはjson形式のシークレットキー的なのを用意しなければいけません。

設定 -> サービスとアカウントからキーの取得ができます。

# Add

データ登録でデータのキーを自動生成する場合に使う

```go
package main

import (
	"context"
	"fmt"

	firebase "firebase.google.com/go"
	"google.golang.org/api/option"
)

func main() {

	ctx := context.Background()
	opt := option.WithCredentialsFile("secret.json")
	app, err := firebase.NewApp(ctx, nil, opt)
	if err != nil {
		fmt.Println(err)
	}

	client, err := app.Firestore(ctx)

	if err != nil {
		fmt.Println(err)
	}

	_, _, err = client.Collection("Users").Add(ctx, map[string]interface{}{
		"name": "First User",
		"age": 11,
		"email": "first@example.com"
	})
	if err != nil {
		fmt.Println(err)
	}
}

```

これでfirestoreにはこのように登録される

![f2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207921/7b8221ae-5a68-0059-cb9d-908deba60e68.png)

キーは一意のものが自動生成される。

ユーザー登録の場合はfirestoreのauthenticationのuidと同じにするとよいかも

# Doc(id).Set()

キーを指定してデータを登録する

```go
package main

import (
	"context"
	"fmt"

	firebase "firebase.google.com/go"
	"google.golang.org/api/option"
)

func main() {

	ctx := context.Background()
	opt := option.WithCredentialsFile("secret.json")
	app, err := firebase.NewApp(ctx, nil, opt)
	if err != nil {
		fmt.Println(err)
	}

	client, err := app.Firestore(ctx)

	if err != nil {
		fmt.Println(err)
	}

	_, err = client.Collection("Users").Doc("1").Set(ctx, map[string]interface{}{
		"name":  "Update",
		"age":   11,
		"email": "first@example.com",
	})
	if err != nil {
		fmt.Println(err)
	}
}

```

これでこんな感じでデータが登録される。

![f1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207921/7a16394a-148a-6614-59a0-e56403a24fd3.png)


データ作成もできるしすでに存在しているキーを指定すればデータの編集ができる。

名前だけ変えたいばあいはfirestore.MergeAllを使わなきゃデータがすべて上書きされてしまう。

正しい例↓

```go
package main

import (
	"context"
	"fmt"

	"cloud.google.com/go/firestore"
	firebase "firebase.google.com/go"
	"google.golang.org/api/option"
)

func main() {

	ctx := context.Background()
	opt := option.WithCredentialsFile("secret.json")
	app, err := firebase.NewApp(ctx, nil, opt)
	if err != nil {
		fmt.Println(err)
	}

	client, err := app.Firestore(ctx)

	if err != nil {
		fmt.Println(err)
	}

	_, err = client.Collection("Users").Doc("1").Set(ctx, map[string]interface{}{
		"name": "Update",
	}, firestore.MergeAll)
	if err != nil {
		fmt.Println(err)
	}
}
```

![f5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207921/289cacb1-7406-fc80-b5e1-a769f2cf4ade.png)


MergeAllを書かないとこのようになる

![f4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207921/c7ab6452-02fc-9a2a-ed13-a54d16a091fc.png)


とりあえずデータ登録に関してはこんな感じ


データの構造としてはドキュメント(Users的な)があってその中にデータを登録していくわけだけどドキュメントの中にさらにドキュメントを作成することも可能

こんな感じ

![f6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207921/4acada3a-f1e6-10ed-99d0-f88e15ec5f94.png)

usersドキュメントのなかにuserのデータがありuserのデータの中にfollower_idというドキュメントがありそのなかにfollower_idのデータが格納される感じ

こんな感じでいくつも階層的にデータを登録していける

登録のしかたは

Collection().Doc().Collection().Add()

みたいにして登録できる

コード↓


```go
package main

import (
	"context"
	"fmt"

	firebase "firebase.google.com/go"
	"google.golang.org/api/option"
)

func main() {

	ctx := context.Background()
	opt := option.WithCredentialsFile("secret.json")
	app, err := firebase.NewApp(ctx, nil, opt)
	if err != nil {
		fmt.Println(err)
	}

	client, err := app.Firestore(ctx)

	if err != nil {
		fmt.Println(err)
	}

	_, _, err = client.Collection("Users").Doc("1").Collection("follower_id").Add(ctx, map[string]interface{}{
		"follower_id": "3",
	})
	if err != nil {
		fmt.Println(err)
	}
}

```

もちろんAdd()ではなくDoc().Set()も使える




おわり:sunny: