ReactNative(Expo)でfirebaseのデータを出力させる

個人的にReactNative初心者がつまずきそうなポイントをまとめました。
ReactNativeでバックエンドにfirebaseを用いることが多いのですが、実際にデータを引っ張ってきてデータを端末に出力させるという一連の流れを詳しく説明している記事が少なく（僕の調べ不足かもしれませんが）、かなり煮詰まった気がしたのでここに載せておきます。

Firebaseのプロジェクトの作成は画面からポチポチやってれば出来るので省略しますね。
https://firebase.google.com/?hl=ja

前提として、firebaseのdatabese(cloudfirebase）にはデータが入っている。
collection名：user
ドキュメント名：自動id
フィールド名：comment, name

今回はhiroshiというデータがnameに入っているとします。


Firebase SDKをインストール。

```
npm i --save firebase
```

firebaseで実際にプロジェクトを作成後、そのプロジェクトのsetting→全般で以下のようなapiが発行されているのでこれをまるっとコピペして、firebase.jsにペースとします。

<img width="615" alt="スクリーンショット 2020-04-22 21.31.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617173/e9cf8cc9-b5a6-6ae5-fc2e-3f72227ae59d.png">


```javascript:firebase.js
export const firebaseConfig = {
  apiKey: "******************",
  authDomain: "******************",
  databaseURL: "******************",
  projectId: "******************",
  storageBucket: "******************",
  messagingSenderId: "******************",
  appId: "******************",
  measurementId: "******************"
};
```

今回はExpoを使います。Expoについて知らない方はググって調べてみてください。


```
$ expo init Sampleproject
$ cd Sampleproject
$ expo start
```

App.jsがプロジェクト内にあると思うので以下のように書き換えてください。

```javascript:App.js
import React from "react";
import { StyleSheet, Text, View, StatusBar, FlatList } from "react-native";
import firebase from "firebase";
import { firebaseConfig } from "./firebase/config"
import {
  Container,
  Content,
} from "native-base";

export default class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      dataItem: "",
      dataSource: []
    };
  }

  componentDidMount() {
    var db = firebaseApp.firestore();
    db.collection("user")
      .get()
      .then(query => {
        var buff = [];
        query.forEach(doc => {
          var data = doc.data();
          buff.push(data);
        });
        this.setState({ dataSource: buff });
      });
  }

  render() {
    return (
      <Container style={styles.container}>
        <Content>
          <FlatList
            data={this.state.dataSource}
            numColumns={2}
            renderItem={({ item }) => {
              return (
                <View style={styles.listItem}>
                  <Text>{item.name}</Text>
                </View>
              );
            }}
            keyExtractor={item => `${item.name}`}
          />
        </Content>
      </Container>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
  }
});
```

<br>
ここからが本題で、僕はこのまま起動すると以下のWarningが出てデータが取得出来ないという状態になりました。なのでそのエラーたちを解決していこうと思います。

####エラー①

```
App named '[DEFAULT]' already exists
```
これは、以下にて解決

```javascript
const firebaseApp = !firebase.apps.length
  ? firebase.initializeApp(firebaseConfig)
  : firebase.app()
```

####エラー②
次にこの部分

```
Unhandled promise rejection: ReferenceError: Can't find variable: atob
```

これは以下の部分を上のソースコードに追加すればいいのと
Firebase SDKの7.9.1以降で発生する問題なので、7.9.0にしてあげれば解決。
その際、キャッシュを消すこと

```javascript
import {decode, encode} from 'base-64'
if (!global.btoa) {  global.btoa = encode }
if (!global.atob) { global.atob = decode }
```

```
$ npm install firebase@7.9.0
$ expo r -c
```

すると、expoの画面で以下のように表示されるはずです
<br>
![S__2457640.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617173/3fd81689-e6d9-e9bf-ebb1-3870cd4619a3.jpeg)


参考文献
https://tech.mof-mof.co.jp/blog/get-started-expo-firestore.html
https://stackoverflow.com/questions/60361519/cant-find-a-variable-atob