LoginSignup
17
14

More than 3 years have passed since last update.

【Flutter】No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()の対処法

Last updated at Posted at 2020-09-05

FlutterのFirebaseサンプルコードにて。

https://codelabs.developers.google.com/codelabs/flutter-firebase/#3

症状

Firebaseのcloud_firestoreパッケージバージョンを、

dependencies:
  flutter:
  cloud_firestore: ^0.14.0+2  // ^0.13.0+1からアップデート

上記のようにアップデートすると、以下のエラーが発生しました。

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following FirebaseException was thrown building MyHomePage(dirty, state: _MyHomePageState#ef74c):
[core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()

対処法:初期化する

Firebase.initializeApp();を追加。

 Widget _buildBody(BuildContext context) {
    Firebase.initializeApp(); // new
    return StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection('baby').snapshots(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) return LinearProgressIndicator();

        return _buildList(context, snapshot.data.documents);
      },
    );
  }

警告の通りですね。

サンプルコードでは、以下の箇所も修正必要でした。

 Record.fromSnapshot(DocumentSnapshot snapshot)
//      : this.fromMap(snapshot.data, reference: snapshot.reference);
      : this.fromMap(snapshot.data(), reference: snapshot.reference);  // new

発展:初期化完了後に処理したい場合

こちらで説明されております。

https://firebase.flutter.dev/docs/overview/#initializing-flutterfire

以下はStatefulWidgetの場合。
_initializedを使って初期化が完了しているかを確認します。

class MyAuthPage extends StatefulWidget {
  @override
  _MyAuthPageState createState() => _MyAuthPageState();
}

class _MyAuthPageState extends State<MyAuthPage> {

  bool _initialized = false;
  bool _error = false;

  // Define an async function to initialize FlutterFire
  void initializeFlutterFire() async {
    try {
      // Wait for Firebase to initialize and set `_initialized` state to true
      await Firebase.initializeApp();
      setState(() {
        _initialized = true;
      });
    } catch (e) {
      // Set `_error` state to true if Firebase initialization fails
      setState(() {
        _error = true;
      });
    }
  }

  @override
  void initState() {
    initializeFlutterFire();
    super.initState();
  }

(省略)

追記:main()の先頭で初期化しちゃう場合

main()Future<void> main() asyncにして対応します。

Future<void> main() async {
  await Firebase.initializeApp();
  runApp(MyApp());
}

ただし、これだけだと、以下のエラーが出ると思います。

If you're running an application and need to access the binary messenger before `runApp()` has been called (for example, during plugin initialization), then you need to explicitly call the `WidgetsFlutterBinding.ensureInitialized()` first.

要約すると、「runApp()の前にプラグインの初期化を行う場合は、はじめに WidgetsFlutterBinding.ensureInitialized() を実行する必要がある」とのこと。

WidgetsFlutterBinding.ensureInitialized()は、最初に初期化することを保証することをFlutterに通知します。

最終的には、以下でOK。

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

参考:[Flutter] WidgetsBindingとは何か?

17
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
14