Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app) と怒られたら

どうもー、

新年あけましておめでとうございます🎍

2021年の書き初めならぬ、技術記事書き初め。

ドイツでフリーランスのフルスタックエンジニアと、[「オーダーメイド感覚プログラミング学習サービス | Lilac（ライレック）」](https://note.com/frontendlifeinde/n/n4e37d4cc5bca?magazine_key=m9b8feda1d547)の開発と運営、講師をしているArisaです。

主には自分のブログとnoteに発信してきましたが、2021年からQiitaの投稿を再開していきたいと思います。

[Lilac](https://note.com/frontendlifeinde/n/n4e37d4cc5bca?magazine_key=m9b8feda1d547)の教材閲覧のためのwebアプリケーション開発をしているのですが、ログイン機能を今実装中です。

が、少々Firebase Authenticationがはまりやすかったので、備忘録、メンテナンスのために書いておきたいと思います。

ざっと調べた感じ、結構みんな落ちるポイントが似ていたので、自分なりにもまとめてみました。

基本はFirebase Authenticationの公式ドキュメントに沿って書いています。

# 状況

- FirebaseUIを使って、マジックリンクでログインできる機能の実装中

Firebase Authenticationの公式ドキュメントに書いてあるとおり、書き進めていくと以下のエラーが出た。

```
Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app) 
```

```
Error: An AuthUI instance already exists for the key "[DEFAULT]"
```

# 環境

- macOS Catalina 10.15.7
- Chrome Canary Version 89.0.4374.0
- [Docz](https://www.docz.site/)（Gatsby.js x TypeScript）
- Firebase Authentication

`firebase` と `firebaseui` をnpmモジュールで導入。

バージョンはそれぞれ以下です。

```javascript
"dependencies": {
  "firebase": "^8.1.1",
  "firebaseui": "^4.7.1",
}
``` 

# Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app)

# 解決策

[公式ドキュメント](https://firebase.google.com/docs/web/setup#using-module-bundlers)で以下のようになっていたのですが、

```javascript
// TODO: Replace the following with your app's Firebase project configuration
// For Firebase JavaScript SDK v7.20.0 and later, `measurementId` is an optional field
const firebaseConfig = {
  // ...
};

// Initialize Firebase
firebase.initializeApp(firebaseConfig);
```

どうも初期化の記述が以下のようにある方が良いと、GithubのissueやStackoverflowを見ても皆さん言っている。

```javascript
// TODO: Replace the following with your app's Firebase project configuration
// For Firebase JavaScript SDK v7.20.0 and later, `measurementId` is an optional field
const firebaseConfig = {
  // ...
};

// Initialize Firebase
// 👇
if (!firebase.apps.length) {
  firebase.initializeApp(firebaseConfig);
}
```

初期化を1回以上すると起こるのだとかで、結構皆さんはまっていた様子でした。

> [Stackoverflowソース](https://stackoverflow.com/questions/43331011/firebase-app-named-default-already-exists-app-duplicate-app)

# 参考にしたソース

- [Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app)](https://www.youtube.com/watch?v=dj9gzLoSYs8)
- [Firebase公式ドキュメント: Easily add sign-in to your Web app with FirebaseUI](https://firebase.google.com/docs/auth/web/firebaseui)
- [FirebaseUI for Web — Auth](https://github.com/firebase/firebaseui-web)

# Error: An AuthUI instance already exists for the key "[DEFAULT]"

# 解決策

[公式ドキュメント](https://firebase.google.com/docs/auth/web/firebaseui#sign_in)でこうなっていたのを

```javascript
// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());
```

こう変更。

```javascript
export const Login = () => {
  const firebaseConfig = {
    // コンフィグ
  };
  // firebase.initializeApp(firebaseConfig)で初期化
}

// Initialize the FirebaseUI Widget using Firebase.
const ui = firebaseui.auth.AuthUI.getInstance() || new firebaseui.auth.AuthUI(firebase.auth());
```

# 反映結果

ログイン前は「Loading...」を表示させるようにして、ログイン後は、プライバシーポリシーなどのリンクを表示します。

まだスタイルはほぼ手をつけていないので、Doczさんのforkリポジトリにしか見えませんが、スタイルは後でまずは機能優先なのであしからず🙏

### Before Login
![Screen Shot 2021-01-02 at 0.32.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178773/074c4b95-4a3b-a9aa-7715-9b3114237c7a.png)

記入したメールアドレス宛にマジックリンクが届くので、クリックすると以下の画面になり、ログイン完了。

### After Login
![Screen Shot 2021-01-02 at 0.38.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178773/04f1e0ab-d80a-d7ac-3646-0702e49e9f79.png)

# 参考にしたソース

- [FirebaseUI 公式リポジトリissue](https://github.com/firebase/firebaseui-web/issues/216)
- [Lua Software Code](https://code.luasoftware.com/tutorials/firebase/error-an-authui-instance-already-exist/)

# まとめ

Doczを使っているので、以下の問題に直面していました。

- Gatsby の TypeScript対応
- Docz が Gatsbyベースでできていることを過信して、Gatsbyプラグインで対応できると信じ込んでいた（TSとの相性悪いのに気がつくのに時間かかり過ぎた）
- Firebase Authenticationの公式ドキュメントに直行せず、quick start的なソースからみて回ったのが、かえって情報に惑わされた

でも結果的にできたのでめでたし。

Doczを使っている人やプロジェクトをあまりまだ見かけないので、もしDocz（TS）でFirebase Authenticationでログイン機能実装したいって人がいれば、参考になれば嬉しいです。

まだまだエンジニアとして成長したいので、「こうした方がいいよ」というアドバイスなどがあれば、コメントしていただけるととても喜びます🙏