terisuke
@terisuke (寺田 康佑)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【Flutter×Firebase】Firebase.initializeAppが2回行われている

解決したいこと

FlutterとFirebaseでTwitterのクローンアプリを作っています。
Flutter runするたびに下記のようにFirebase.initializeAppが複数回行われてしまい、
エミュレーター画面が真っ白のまま先に進みません。
全テキスト検索をしてもmain.dart以外では呼び出されておらず、どうしたらいいか途方に暮れています。
おそらく使用しているパッケージかプラグインが別にFirebase.initializeAppを呼び出しているのではないかと思うのですが、特定ができない状況です。

発生している問題・エラー

Xcode build done.                                           18.4s
[VERBOSE-2:FlutterDarwinContextMetalImpeller.mm(37)] Using the Impeller rendering backend.
flutter: Firebase initializing...
flutter: Firebase initialization failed
flutter: Error: [core/duplicate-app] A Firebase App named "[DEFAULT]" already exists
flutter: StackTrace: #0      MethodChannelFirebase.initializeApp (package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart:134:11)
<asynchronous suspension>
#1      Firebase.initializeApp (package:firebase_core/src/firebase.dart:43:31)
<asynchronous suspension>
#2      main.<anonymous closure> (package:udemy_flutter_sns/main.dart:41:9)
<asynchronous suspension>
#3      main (package:udemy_flutter_sns/main.dart:33:3)
<asynchronous suspension>
Syncing files to device iPhone 15 Pro Max...            

該当するソースコード

main.dart
//dart
import 'dart:async';
// flutter
import 'package:flutter/material.dart';
// packages
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:udemy_flutter_sns/constants/others.dart';
// models
import 'package:udemy_flutter_sns/models/main_model.dart';
import 'package:udemy_flutter_sns/models/mute_users_model.dart';
import 'package:udemy_flutter_sns/models/sns_bottom_navigation_bar_model.dart';
import 'package:udemy_flutter_sns/models/themes_model.dart';
// options
import 'firebase_options.dart';
// constants
import 'package:udemy_flutter_sns/constants/strings.dart';
import 'package:udemy_flutter_sns/constants/themes.dart';
// components
import 'package:udemy_flutter_sns/views/main/articles_screen.dart';
import 'package:udemy_flutter_sns/views/auth/verify_email_page.dart';
import 'package:udemy_flutter_sns/details/sns_bottom_navigation_bar.dart';
import 'package:udemy_flutter_sns/views/login_page.dart';
import 'package:udemy_flutter_sns/views/main/home_screen.dart';
import 'package:udemy_flutter_sns/views/main/search_page.dart';
import 'package:udemy_flutter_sns/views/main/profile_screen.dart'; // CupertinoWidgetsのためにimport追加

Future<void> main() async {
  await runZonedGuarded(() async {
    WidgetsFlutterBinding.ensureInitialized();
    await dotenv.load();

    // Firebaseがまだ初期化されていない場合のみ、初期化を行う
    if (Firebase.apps.isEmpty) {
      try {
        print("Firebase initializing..."); // ← この行を追加
        await Firebase.initializeApp(
            options: DefaultFirebaseOptions.currentPlatform);
        print("Firebase initialized successfully."); // ← この行を追加
      } catch (e, stackTrace) {
        print('Firebase initialization failed');
        print('Error: $e');
        print('StackTrace: $stackTrace');
        return;
      }
    }

    runApp(const ProviderScope(child: MyApp()));
  }, (error, stackTrace) {
    if (Firebase.apps.isNotEmpty) {
      FirebaseCrashlytics.instance.recordError(error, stackTrace);
    } else {
      print('Error occurred, but Firebase is not initialized');
      print('Error: $error');
      print('StackTrace: $stackTrace');
    }
  });
}
class MyApp extends ConsumerWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // FirebaseCrashlyticsインスタンスをここで設定します。
    FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
    final User? onceUser = FirebaseAuth.instance.currentUser;
    final ThemeModel themeModel = ref.watch(themeProvider);

    // FutureBuilderは必要ないため、直接MaterialAppを返します。
    return MaterialApp(
      localizationsDelegates: AppLocalizations.localizationsDelegates,
      supportedLocales: AppLocalizations.supportedLocales,
      debugShowCheckedModeBanner: false,
      title: appTitle,
      theme: themeModel.isDarkTheme
          ? darkThemeData(context: context)
          : lightThemeData(context: context),
      home: onceUser == null
          ? const LoginPage()
          : onceUser.emailVerified
              ? MyHomePage(
                  themeModel: themeModel,
                )
              : const VerifyEmailPage(),
    );
  }
}

class SomethingWentWrong extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('Something went wrong!'),
      ),
    );
  }
}

class Loading extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: CircularProgressIndicator(),
      ),
    );
  }
}

class MyHomePage extends ConsumerWidget {
  const MyHomePage({Key? key, required this.themeModel}) : super(key: key);
  final ThemeModel themeModel;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // MainModelが起動し、init()が実行されます
    final MainModel mainModel = ref.watch(mainProvider);
    final SNSBottomNavigationBarModel snsBottomNavigationBarModel =
        ref.watch(snsBottomNavigationBarProvider);
    return Scaffold(
      body: mainModel.isLoading
          ? Center(
              child: Text(returnL10n(context: context)!.loading),
            )
          : PageView(
              controller: snsBottomNavigationBarModel.pageController,
              onPageChanged: (index) =>
                  snsBottomNavigationBarModel.onPageChanged(index: index),
              // childrenの個数はElementsの数
              children: [
                // 注意:ページじゃないのでScaffold
                HomeScreen(
                  mainModel: mainModel,
                  themeModel: themeModel,
                  muteUsersModel: MuteUsersModel(),
                ),
                SearchPage(
                  mainModel: mainModel,
                ),
                const ArticlesScreen(),
                ProfileScreen(
                  mainModel: mainModel,
                ),
              ],
            ),
      bottomNavigationBar: SNSBottomNavigationBar(
          snsBottomNavigationBarModel: snsBottomNavigationBarModel),
    );
  }
}

自分で試したこと

エラーハンドリング(print~)を細かくつけて、initializeAppが複数回呼び出されているところまで特定した。
他の.dartで呼び出されていないか確認して、コメントアウトされているところまで削除した。

GitHubコード
https://github.com/terisuke/FlutterSNS/tree/develop

0

1Answer

Comments

  1. @terisuke

    Questioner

    ありがとうございます!!
    こちらでアンドロイド、IOSともにエミュレーターが動きました!

  2. よかったですね✌️
    解決であれば、当Q&Aをクローズしてください。

Your answer might help someone💌