Flutter使用Stream与Provider实现登录退出功能时报错如何解决
问题解决方法
两个报错均为Flutter空安全特性导致,旧教程未适配空安全所以没有对应配置,修改方案如下:
1 修复auth.dart类型不匹配错误
- 原因:Firebase的
authStateChanges()方法返回的流是Stream<User?>类型,流中可以 emit 空值(用户未登录状态),你之前的map回调参数强制声明为非空User类型,和上游流类型不匹配。同时_userFromFirebaseUser方法参数也要同步改为可空类型。 - 完整修改后auth.dart代码:
import 'package:firebase_auth/firebase_auth.dart'; import 'package:wasthu/Services/user.dart'; class AuthService { final FirebaseAuth _auth = FirebaseAuth.instance; //create userobject based on firebase user Userid? _userFromFirebaseUser(User? user) { return user != null ? Userid(uid: user.uid) : null; } // auth change user stream Stream<Userid?> get user { return _auth .authStateChanges() .map((User? user) => _userFromFirebaseUser(user)); } //sign in anon Future signInAnon() async { try { UserCredential result = await _auth.signInAnonymously(); User? user = result.user; return _userFromFirebaseUser(user); } catch (e) { print(e.toString()); return null; } } //signout Future signOut() async { try { return await _auth.signOut(); } catch (e) { print(e.toString()); return null; } } }
2 修复main.dart中initialData不能为null错误
- 原因:你之前声明的
StreamProvider<Userid>泛型为非空类型,不允许传入null作为初始值,修改泛型为可空的Userid?即可。 - 完整修改后main.dart代码:
import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:wasthu/Screens/Home/wrapper.dart'; import 'package:wasthu/Services/auth.dart'; import 'package:wasthu/Services/user.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); runApp(MaterialApp( home: MyApp(), debugShowCheckedModeBanner: false, )); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return StreamProvider<Userid?>.value( value: AuthService().user, initialData: null, child: MaterialApp( home: Wrapper(), ), ); } }
后续使用注意
在Wrapper页面中读取Provider.of<Userid?>(context)时,先判断是否为null,null对应未登录状态,非null对应已登录状态即可。
内容的提问来源于stack exchange,提问作者Afrij
相关产品推荐
相关产品推荐

