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


どうもー、

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

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

ドイツでフリーランスのフルスタックエンジニアと、「オーダーメイド感覚プログラミング学習サービス | Lilac(ライレック)」の開発と運営、講師をしているArisaです。

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

Lilacの教材閲覧のための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(Gatsby.js x TypeScript)
  • Firebase Authentication

firebasefirebaseui をnpmモジュールで導入。

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

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

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

解決策

公式ドキュメントで以下のようになっていたのですが、

// 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を見ても皆さん言っている。

// 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ソース

参考にしたソース

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

解決策

公式ドキュメントでこうなっていたのを

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

こう変更。

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

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

After Login

参考にしたソース

まとめ

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

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

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

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

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