簡體   English   中英

依賴於 firebase 的根提供程序在 Firebase.initializeApp() 完成之前獲取值

[英]Provider at root dependent on firebase fetches value before Firebase.initializeApp() completes

因此,我正在構建一個帶有 MultiProviders 的應用程序,該應用程序位於 MaterialApp() 之上的應用程序的根目錄上(以便該值在我導航到的所有子小部件和后續頁面中都可用)。

對於我的主 function:

void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
   }

MyApp class 在哪里:

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  DarkThemeProvider themeChangeProvider = DarkThemeProvider();
  final Future<FirebaseApp> _firebaseApp = Firebase.initializeApp();

  void getCurrentAppTheme() async {
    themeChangeProvider.darkTheme =
    await themeChangeProvider.darkThemePreference.getTheme();
  }

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

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (_) => themeChangeProvider,
        ),
        ChangeNotifierProvider(
          create: (_) => VideoPlayService.instance(),
        ),
        ChangeNotifierProvider(
          create: (_) => FirestoreAPI.instance(),
        ),
        ChangeNotifierProvider(
          create: (_) => AuthUtil.instance(),
        ),
        ChangeNotifierProvider(
          create: (_) => PageSwitcher.instance(),
        ),
      ],
      child: Consumer5(
        builder: (
          ctx,
          DarkThemeProvider darkThemeProvider,
          VideoPlayService videoPlayService,
          FirestoreAPI firestoreAPI,
          AuthUtil user,
          PageSwitcher switcher,
          child,
        ) {
          return MaterialApp(
            debugShowCheckedModeBanner: false,
            themeMode: Provider.of<DarkThemeProvider>(ctx).getCurrentTheme,
            theme: DarkThemeProvider.customLightTheme,
            darkTheme: DarkThemeProvider.customDarkTheme,
            home: FutureBuilder(
              future: _firebaseApp,
              builder: (cx, snapshot) {
                if (snapshot.hasError) {
                  return const Center(
                    child: Text('Could not connect to firebase'),
                  );
                } else if (snapshot.connectionState == ConnectionState.done) {
                  return const Wrapper();
                } else {
                  return const SplashScreen();
                }
              },
            ),
          );
        },
      ),
    );
  }
}

我已經使用未來構建器使用 Firebase 初始化應用程序,但問題是提供者 AuthUtil 和 FirestoreAPI 都依賴於 firebase,現在如果我要刪除這兩個並將它們作為子項添加到未來構建器(包裝器上方)我將失去對我整個應用程序中提供者的訪問權限(因為提供者將不再位於根目錄,它只對第一個孩子可用,無論何時我導航到另一個頁面,它都將不可用)。

在我編寫的給定代碼中,firebase 未初始化,但首先創建了 Provider 的實例,因此拋出 firebase 未初始化的異常,我還需要能夠在 Firebase 初始化時顯示 SplashScreen,我試圖我全神貫注於未來的供應商,但我不確定它們是如何工作的,甚至不確定它們是否與我的案例相關。

總而言之,我想先初始化 firebase,然后創建 AuthUtil 和 FirestoreAPI 的提供者 class,同時保持在 firebase 初始化失敗時顯示啟動畫面或錯誤屏幕的方案,並將提供者保持在根目錄(為了記錄,我確實嘗試制作了一個FutureBuilder 位於根目錄,但它沒有意義,我必須為快照的情況調用多個 MaterialApp,這簡直是無稽之談)。

如果有人可以幫助我盡快解決這個問題......? 這將是一個很好的節省。

我通常在 main 方法中調用initializeApp

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

雖然initializeApp調用是異步的,但它實際上只是對底層原生 SDK 的同步調用。 所以我們在這里談論等待納秒,而不是幾十到幾百毫秒,在FutureBuilder有意義的地方。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM