[英]How to initialize Firebase via Riverpod's FutureProvider
在 Flutter 應用程序中使用 Firebase 的第一步是執行初始化。
我已經嘗試在 main() 中這樣做並且它有效
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
I've utilized Riverpod for state management - with Provider for firebase instance and access to the class with connection methods (Signin, Signout...) and StreamProvider for user state. 這再次工作正常 - 識別用戶何時登錄或退出 - 重建小部件並重定向到正確的屏幕......
現在我還想將上面粘貼的代碼從 main() 移動到提供程序定義中,並根據 firebase 初始化的狀態顯示正確的屏幕。
我已經看到官方 Firebase 示例建議為此使用 FutureBuilder - 但是,由於我使用過 Riverpod - 我的想法是使用FutureProvider
來初始化 firebase。 但是,無論我嘗試什么,該應用程序都會因一些 null 異常而崩潰。
如果有人可以通過 FutureProvider 分享他們的firebase.initializeApp()
示例,那就太好了。
我這樣做:(如果需要,可以通過 singleton 完成)
// services_initialization.dart
class ServiceInit{
ServiceInit(ProviderContainer container) {
_container = container;
}
// The container is needed to access the ref and load other providers, if required
late final ProviderContainer _container;
Future<void> init() async {
await _initFirebase();
// initialization of other services, example:
await _container.read(somethingFutureProvider.future);
}
Future<void> _initFirebase() async {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
}
}
主文件如下所示:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final _container = ProviderContainer();
await ServiceInit(_container).init();
runApp(UncontrolledProviderScope(
container: _container,
child: WeatherMain(),
),
}
我已經找到了解決方案,因此將其粘貼在下面。 非常感謝 2002Bishwajeet,他在 GitHub 上發布了涵蓋此主題的 Firebase 和Riverpod身份驗證示例
這個想法是像這樣創建 FutureProvider :
final firebaseInitProvider = FutureProvider<FirebaseApp>((ref) async
{
return await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
});
在 main() 中只保留WidgetsFlutterBinding.ensureInitialized()
像這樣:
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(ProviderScope(child: const MyApp()));
}
然后觀察提供者和 use.when() 以顯示正確的屏幕 - 基本上只有在 Firebase.initializeApp() 完成初始化過程后才移動到 AuthenticationWrapper 小部件。
像這樣:
class MyApp extends ConsumerWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final _initializeFirebase = ref.watch(firebaseInitProvider);
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Firebase Authentication App',
theme: CommonTheme().mainThemeData,
home: _initializeFirebase.when(
data: (data) => const AuthenticationWrapper(),
loading: () => const ProgressScreen(),
error: (error, stackTrace) => ErrorScreen(error.toString()),
),
);
}
}
最后,AuthenticationWrapper 正在處理登錄或主屏幕的顯示 - 取決於用戶的狀態(是否已在 Firebase Auth 登錄)。
像這樣:
class AuthenticationWrapper extends ConsumerWidget {
const AuthenticationWrapper({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final _authState = ref.watch(authStateProvider);
return _authState.when(
data: (value) {
if (value != null) {
return HomeScreen();
} else {
return LoginScreen();
}
},
error: ((error, stackTrace) => ErrorScreen(error.toString())), //TO-DO set user oriented error messages
loading: (() => ProgressScreen()),
);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.