[英]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.