ExpoにFirebaseを導入する手順

# ExpoにFirebaseを導入する手順
## 目的
- まずはExpoからfirebaseへの疎通まで
- firestoreへExpoのiosアプリから値が登録できるまでをゴール
- authで匿名ログインをするまでが第２のゴール

## 構成
- Firebase 
- react-native
- expo
- Firebase JavaScript SDK 3.1+

## 備考
- Expoのツールを導入するぐらいで、後の操作は javascriptによるFirebase利用と同じ操作ができる
- 一部react-nativeでは使えない機能がある（通知など）それらは別途、cloud function経由でExpoのAPIで実現する、などが必要。別記事で改めて手順化する

## ガイド
> Expo公式ドキュメント
> https://docs.expo.io/guides/using-firebase/

## Firestore導入の手順
### expoにfirebaseを導入
`expo install firebase`

### AppにApiKeyを設定

```
import * as firebase from 'firebase';

// Optionally import the services that you want to use
//import "firebase/auth";
//import "firebase/database";
//import "firebase/firestore";
//import "firebase/functions";
//import "firebase/storage";

// Initialize Firebase
const firebaseConfig = {
  // firebaseから発行される
};

firebase.initializeApp(firebaseConfig);

```

1. firebaseのdatabase側のアクセス制限を一応確認
2. cloud consoleに入り
3. databaseを作成
4. ルールタブを確認、許可されていることを確認する

### firestoreを使う

1 importにfirestoreを追加する


```
import * as firebase from 'firebase';
import 'firebase/firestore';
```

2 firestoreのインスタンスを用意する

```
const dbh = firebase.firestore();
```

3 firestoreを操作する

- ここまで出来れば、あとあ通常のwebと同じ方法でfirestoreを操作

```
dbh.collection("users").doc("test").set({
      score: 100,
      employment: "plumber",
      outfitColor: "red",
      specialAttack: "fireball"
})
```

```
firestoreのインスタンス.collection(firestoreに用意したコレクション名).doc(特定ユーザのキー).set({
	jsonで設定値を当てる
)}
```

4 firestoreを使うための最小限のクラス設定まとめ

```
import React from 'react';
import * from 'react-native';

// firebase
import * as firebase from 'firebase';
import 'firebase/firestore';


const firebaseConfig = {
  api:keyとか
};

firebase.initializeApp(firebaseConfig);

//クラス
class Sample extends React.Component {

onStartButtonPress = () => {

      dbh.collection("users").doc("test").set({
        keyと:値
      })
}

render() {

    return (

      <View>
	<Button
          title='Firebaseはじめる'
          onPress={this.onStartButtonPress}
           />

      </View>
    );
  }

}

```

## authでの匿名ログイン導入の手順
### 参考資料
> https://firebase.google.com/docs/auth/web/anonymous-auth?hl=ja


### Firebase側の設定
- cloud console上でAuthenticationメニューを開く
- ログイン方法を選択し、有効化する
- 端末からログインが行われると、Usersのリスト上に

### signInAnonymouslyを実装する
- エラーハンドリングを行う

```
firebase.auth().signInAnonymously().catch(function(error){
  var errorCode = error.code;
  var errorMessage = error.message;
  console.log(error);
});
```

1 ログインしたユーザの取得

```
firebase.auth().onAuthStateChanged(function(user){
  if(user){
    // ログイン時の処理
    var isAnonymous = user.isAnonymous;
    var uid = user.uid;
  } else {
    // ログアウト処理

  }
});

```

- この状態で cloud consoleから確認すると、端末のuidのユーザがログインしていることを確認できる
- __[ハマったポイント]__ 現在ログインしているユーザは以下で取得できるが、この時nullになってしまう場合がある

```
firebase.auth().currentUser;
```

> https://firebase.google.com/docs/auth/web/manage-users?hl=ja

- 原因は、Authオブジェクトがまだ初期化できておらず、匿名ログインができていない状態
- そのため、起動した直後にユーザの情報を取得する場合は `onAuthStateChanged` のコールバックのなかで行う必要がある

```
例 起動した匿名ユーザのdisplaynameを取得する
user = firebase.auth().currentUser;
user.displayname -> NULLになる

```

```
firebase.auth().onAuthStateChanged(function(user){
 user.displayname　->取得できる
});

```



2 別の方法のログインと関連づける方法

- 匿名ログインのアカウントと、別の方法（メールアドレスとパスワード）で作ったアカウントを関連づける
- 他の認証方法から、credentialを作成する


```
var credential = firebase.auth.EmailAuthProvider.credential("メールアドレス", "パスワード");
```

- credentialを、現在ログインしている匿名ユーザと `link` メソッドで関連づける

```
auth.currentUser.linkWithCredential(credential)
  .then(function(usercred) {
    var user = usercred.user;
    console.log("Anonymous account successfully upgraded", user);
  }).catch(function(error) {
    console.log("Error upgrading anonymous account", error);
  });
```