如何解决Provider.of总是返回null Flutter
Flutter channel stable
Flutter upgrade
现在,它始终返回null。
import 'dart:io';
import 'package:Flutter/cupertino.dart';
import 'package:Flutter/material.dart';
import 'package:boots/helper/enum.dart';
import 'package:boots/helper/theme.dart';
import 'package:boots/page/Auth/selectAuthMethod.dart';
import 'package:boots/page/homePage.dart';
import 'package:boots/state/authState.dart';
import 'package:boots/widgets/customWidgets.dart';
import 'package:provider/provider.dart';
class SplashPage extends StatefulWidget {
SplashPage({Key key}) : super(key: key);
@override
_SplashPageState createState() => _SplashPageState();
}
class _SplashPageState extends State<SplashPage> {
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
timer();
});
super.initState();
}
void timer() async {
Future.delayed(Duration(seconds: 1)).then((_) {
var state = Provider.of<AuthState>(context,listen: false);
state.getCurrentUser();
});
}
Widget _body() {
var height = 150.0;
return Container(
height: fullHeight(context),width: fullWidth(context),child: Container(
height: height,width: height,alignment: Alignment.center,child: Container(
padding: EdgeInsets.all(50),decoration: Boxdecoration(
color: Colors.white,borderRadius: BorderRadius.all(
Radius.circular(10),),child: Stack(
alignment: Alignment.center,children: <Widget>[
Platform.isIOS
? CupertinoActivityIndicator(
radius: 35,)
: CircularProgressIndicator(
strokeWidth: 2,Image.asset(
'assets/images/icon-480.png',height: 30,width: 30,)
],);
}
@override
Widget build(BuildContext context) {
var state = Provider.of<AuthState>(context);
return Scaffold(
backgroundColor: TwitterColor.white,body: state.authStatus == AuthStatus.NOT_DETERmineD
? _body()
: state.authStatus == AuthStatus.NOT_LOGGED_IN
? WelcomePage()
: HomePage(),);
}
}
这是罪魁祸首:
void timer() async {
Future.delayed(Duration(seconds: 1)).then((_) {
var state = Provider.of<AuthState>(context,listen: false);
state.getCurrentUser();
});
}
我的main.dart是我为AuthState设置ChangeNotifierProvider的地方,看起来像:
import 'package:boots/blocs/place_bloc.dart';
import 'package:boots/helper/locator.dart';
import 'package:boots/state/communitiesstate.dart';
import 'package:boots/state/mapState.dart';
import 'package:Flutter/material.dart';
import 'package:boots/helper/theme.dart';
import 'package:boots/state/searchState.dart';
import 'package:boots/state/nearbyState.dart';
import 'package:Flutter/services.dart';
import 'helper/routes.dart';
import 'state/appState.dart';
import 'package:provider/provider.dart';
import 'state/authState.dart';
import 'state/chats/chatState.dart';
import 'state/FeedState.dart';
import 'package:google_fonts/google_fonts.dart';
import 'state/notificationState.dart';
void main() {
setupLocator();
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setsystemUIOverlayStyle(
systemUIOverlayStyle(statusBarColor: AppColor.primary));
return MultiProvider(
providers: [
ChangeNotifierProvider<AppState>(create: (_) => AppState()),ChangeNotifierProvider<AuthState>(create: (_) => AuthState()),ChangeNotifierProvider<FeedState>(create: (_) => FeedState()),ChangeNotifierProvider<ChatState>(create: (_) => ChatState()),ChangeNotifierProvider<SearchState>(create: (_) => SearchState()),ChangeNotifierProvider<NotificationState>(
create: (_) => NotificationState()),ChangeNotifierProvider<MapState>(create: (_) => MapState()),ChangeNotifierProvider<Communitiesstate>(
create: (_) => Communitiesstate()),ChangeNotifierProvider<NearbyState>(create: (_) => NearbyState()),ChangeNotifierProvider<PlaceBloc>(create: (_) => PlaceBloc()),],child: MaterialApp(
title: 'Boots',theme: AppTheme.apptheme.copyWith(
textTheme: GoogleFonts.muliTextTheme(
Theme.of(context).textTheme,debugShowCheckedModeBanner: false,routes: Routes.route(),// goes to splash.dart
onGenerateRoute: (settings) => Routes.onGenerateRoute(settings),onUnkNownRoute: (settings) => Routes.onUnkNownRoute(settings),);
}
}
最后,我的AuthState类如下:
import 'dart:io';
import 'package:firebase_auth/firebase_auth.dart' as firebaseauth;
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:Flutter/material.dart';
import 'package:Flutter/services.dart';
import 'package:boots/helper/enum.dart';
import 'package:boots/helper/utility.dart';
import 'package:boots/model/user.dart';
import 'package:boots/widgets/customWidgets.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:path/path.dart' as Path;
import 'appState.dart';
import 'package:firebase_database/firebase_database.dart' as dabase;
class AuthState extends AppState {
AuthStatus authStatus = AuthStatus.NOT_DETERmineD;
bool isSignInWithGoogle = false;
firebaseauth.User user;
String userId;
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
final firebaseauth.FirebaseAuth _firebaseAuth =
firebaseauth.FirebaseAuth.instance;
final GoogleSignIn _googleSignIn = GoogleSignIn();
dabase.Query _profileQuery;
List<User> _profileusermodelList;
User _usermodel;
User get usermodel => _usermodel;
User get profileusermodel {
if (_profileusermodelList != null && _profileusermodelList.length > 0) {
return _profileusermodelList.last;
} else {
return null;
}
}
void removeLastUser() {
_profileusermodelList.removeLast();
}
/// logout from device
void logoutCallback() {
authStatus = AuthStatus.NOT_LOGGED_IN;
userId = '';
_usermodel = null;
user = null;
_profileusermodelList = null;
if (isSignInWithGoogle) {
_googleSignIn.signOut();
logEvent('google_logout');
}
_firebaseAuth.signOut();
notifyListeners();
}
/// Alter select auth method,login and sign up page
void openSignUpPage() {
authStatus = AuthStatus.NOT_LOGGED_IN;
userId = '';
notifyListeners();
}
databaseInit() {
try {
if (_profileQuery == null) {
_profileQuery = kDatabase.child("profile").child(user.uid);
_profileQuery.onValue.listen(_onProfileChanged);
}
} catch (error) {
cprint(error,errorIn: 'databaseInit');
}
}
/// Verify user's credentials for login
Future<String> signIn(String email,String password,{GlobalKey<ScaffoldState> scaffoldKey}) async {
try {
loading = true;
var result = await _firebaseAuth.signInWithEmailAndPassword(
email: email,password: password);
user = result.user;
userId = user.uid;
return user.uid;
} catch (error) {
loading = false;
cprint(error,errorIn: 'signIn');
kAnalytics.logLogin(loginMethod: 'email_login');
customSnackBar(scaffoldKey,error.message);
// logoutCallback();
return null;
}
}
/// Create user from `google login`
/// If user is new then it create a new user
/// If user is old then it just `authenticate` user and return firebase user data
Future<firebaseauth.User> handleGoogleSignIn() async {
try {
/// Record log in firebase kAnalytics about Google login
kAnalytics.logLogin(loginMethod: 'google_login');
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
if (googleUser == null) {
throw Exception('Google login cancelled by user');
}
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;
final firebaseauth.AuthCredential credential =
firebaseauth.GoogleAuthProvider.credential(
accesstoken: googleAuth.accesstoken,idToken: googleAuth.idToken,);
user = (await _firebaseAuth.signInWithCredential(credential)).user;
authStatus = AuthStatus.LOGGED_IN;
userId = user.uid;
isSignInWithGoogle = true;
createuserFromGoogleSignIn(user);
notifyListeners();
return user;
} on PlatformException catch (error) {
user = null;
authStatus = AuthStatus.NOT_LOGGED_IN;
cprint(error,errorIn: 'handleGoogleSignIn');
return null;
} on Exception catch (error) {
user = null;
authStatus = AuthStatus.NOT_LOGGED_IN;
cprint(error,errorIn: 'handleGoogleSignIn');
return null;
} catch (error) {
user = null;
authStatus = AuthStatus.NOT_LOGGED_IN;
cprint(error,errorIn: 'handleGoogleSignIn');
return null;
}
}
/// Create user profile from google login
createuserFromGoogleSignIn(firebaseauth.User user) {
var diff = DateTime.Now().difference(user.Metadata.creationTime);
// Check if user is new or old
// If user is new then add new user to firebase realtime kDatabase
if (diff < Duration(seconds: 15)) {
User model = User(
bio: 'Edit profile to update bio',dob: DateTime(1950,DateTime.Now().month,DateTime.Now().day + 3)
.toString(),location: 'Somewhere in universe',profilePic: user.photoURL,displayName: user.displayName,email: user.email,key: user.uid,userId: user.uid,contact: user.phoneNumber,isverified: user.emailVerified,);
createuser(model,newUser: true);
} else {
cprint('Last login at: ${user.Metadata.lastSignInTime}');
}
}
/// Create new user's profile in db
Future<String> signUp(User usermodel,{GlobalKey<ScaffoldState> scaffoldKey,String password}) async {
try {
loading = true;
var result = await _firebaseAuth.createuserWithEmailAndPassword(
email: usermodel.email,password: password,);
user = result.user;
authStatus = AuthStatus.LOGGED_IN;
kAnalytics.logSignUp(signUpMethod: 'register');
await result.user.updateProfile(
displayName: usermodel.displayName,photoURL: usermodel.profilePic,);
_usermodel = usermodel;
_usermodel.key = user.uid;
_usermodel.userId = user.uid;
createuser(_usermodel,newUser: true);
return user.uid;
} catch (error) {
loading = false;
cprint(error,errorIn: 'signUp');
customSnackBar(scaffoldKey,error.message);
return null;
}
}
/// `Create` and `Update` user
/// IF `newUser` is true new user is created
/// Else existing user will update with new values
createuser(User user,{bool newUser = false}) {
if (newUser) {
// Create username by the combination of name and id
user.userName = getUserName(email: user.email);
kAnalytics.logEvent(name: 'create_newUser');
// Time at which user is created
user.createdAt = DateTime.Now().toUtc().toString();
}
kDatabase.child('profile').child(user.userId).set(user.toJsonUpdate());
_usermodel = user;
if (_profileusermodelList != null) {
_profileusermodelList.last = _usermodel;
}
loading = false;
}
/// Fetch current user profile
Future<firebaseauth.User> getCurrentUser() async {
try {
loading = true;
logEvent('get_currentUSer');
user = _firebaseAuth != null ? _firebaseAuth.currentUser : null;
if (user != null) {
authStatus = AuthStatus.LOGGED_IN;
userId = user.uid;
getProfileUser();
} else {
authStatus = AuthStatus.NOT_LOGGED_IN;
}
loading = false;
return user;
} catch (error) {
loading = false;
cprint(error,errorIn: 'getCurrentUser');
authStatus = AuthStatus.NOT_LOGGED_IN;
return null;
}
}
/// Reload user to get refresh user data
reloadUser() async {
await user.reload();
user = _firebaseAuth.currentUser;
if (user.emailVerified) {
usermodel.isverified = true;
// If user verifed his email
// Update user in firebase realtime kDatabase
createuser(usermodel);
cprint('User email verification complete');
logEvent('email_verification_complete',parameter: {usermodel.userName: user.email});
}
}
/// Send email verification link to email2
Future<void> sendEmailVerification(
GlobalKey<ScaffoldState> scaffoldKey) async {
firebaseauth.User user = _firebaseAuth.currentUser;
user.sendEmailVerification().then((_) {
logEvent('email_verifcation_sent',parameter: {usermodel.displayName: user.email});
customSnackBar(
scaffoldKey,'An email verification link is send to your email.',);
}).catchError((error) {
cprint(error.message,errorIn: 'sendEmailVerification');
logEvent('email_verifcation_block',error.message,);
});
}
/// Check if user's email is verified
Future<bool> isEmailVerified() async {
firebaseauth.User user = _firebaseAuth.currentUser;
return user.emailVerified;
}
/// Send password reset link to email
Future<void> forgetpassword(String email,{GlobalKey<ScaffoldState> scaffoldKey}) async {
try {
await _firebaseAuth.sendPasswordResetEmail(email: email).then((value) {
customSnackBar(scaffoldKey,'A reset password link is sent yo your mail.You can reset your password from there');
logEvent('forgot+password');
}).catchError((error) {
cprint(error.message);
return false;
});
} catch (error) {
customSnackBar(scaffoldKey,error.message);
return Future.value(false);
}
}
/// `Update user` profile
Future<void> updateUserProfile(User usermodel,{File image}) async {
try {
if (image == null) {
createuser(usermodel);
} else {
Reference storageReference = FirebaseStorage.instance
.ref()
.child('user/profile/${Path.basename(image.path)}');
UploadTask uploadTask = storageReference.putFile(image);
await uploadTask.then((value) {
storageReference.getDownloadURL().then((fileURL) async {
print(fileURL);
await user.updateProfile(
displayName: usermodel?.displayName ?? user.displayName,photoURL: fileURL,);
if (usermodel != null) {
usermodel.profilePic = fileURL;
createuser(usermodel);
} else {
_usermodel.profilePic = fileURL;
createuser(_usermodel);
}
});
});
}
logEvent('update_user');
} catch (error) {
cprint(error,errorIn: 'updateUserProfile');
}
}
/// `Fetch` user `detail` whoose userId is passed
Future<User> getuserDetail(String userId) async {
User user;
var snapshot = await kDatabase.child('profile').child(userId).once();
if (snapshot.value != null) {
var map = snapshot.value;
user = User.fromJson(map);
user.key = snapshot.key;
return user;
} else {
return null;
}
}
/// Fetch user profile
/// If `userProfileId` is null then logged in user's profile will fetched
getProfileUser({String userProfileId}) {
try {
loading = true;
if (_profileusermodelList == null) {
_profileusermodelList = [];
}
userProfileId = userProfileId == null ? user.uid : userProfileId;
kDatabase
.child("profile")
.child(userProfileId)
.once()
.then((DataSnapshot snapshot) {
if (snapshot.value != null) {
var map = snapshot.value;
if (map != null) {
_profileusermodelList.add(User.fromJson(map));
if (userProfileId == user.uid) {
_usermodel = _profileusermodelList.last;
_usermodel.isverified = user.emailVerified;
if (!user.emailVerified) {
// Check if logged in user verified his email address or not
reloadUser();
}
if (_usermodel.fcmToken == null) {
updateFCMToken();
}
}
logEvent('get_profile');
}
}
loading = false;
});
} catch (error) {
loading = false;
cprint(error,errorIn: 'getProfileUser');
}
}
/// if firebase token not available in profile
/// Then get token from firebase and save it to profile
/// When someone sends you a message FCM token is used
void updateFCMToken() {
if (_usermodel == null) {
return;
}
getProfileUser();
_firebaseMessaging.getToken().then((String token) {
assert(token != null);
_usermodel.fcmToken = token;
createuser(_usermodel);
});
}
/// Follow / Unfollow user
///
/// If `removeFollower` is true then remove user from follower list
///
/// If `removeFollower` is false then add user to follower list
followUser({bool removeFollower = false}) {
/// `usermodel` is user who is looged-in app.
/// `profileusermodel` is user whoose profile is open in app.
try {
if (removeFollower) {
/// If logged-in user `alredy follow `profile user then
/// 1.Remove logged-in user from profile user's `follower` list
/// 2.Remove profile user from logged-in user's `following` list
profileusermodel.followersList.remove(usermodel.userId);
/// Remove profile user from logged-in user's following list
usermodel.followingList.remove(profileusermodel.userId);
cprint('user removed from following list',event: 'remove_follow');
} else {
/// if logged in user is `not following` profile user then
/// 1.Add logged in user to profile user's `follower` list
/// 2. Add profile user to logged in user's `following` list
if (profileusermodel.followersList == null) {
profileusermodel.followersList = [];
}
profileusermodel.followersList.add(usermodel.userId);
// Adding profile user to logged-in user's following list
if (usermodel.followingList == null) {
usermodel.followingList = [];
}
usermodel.followingList.add(profileusermodel.userId);
}
// update profile user's user follower count
profileusermodel.followers = profileusermodel.followersList.length;
// update logged-in user's following count
usermodel.following = usermodel.followingList.length;
kDatabase
.child('profile')
.child(profileusermodel.userId)
.child('followerList')
.set(profileusermodel.followersList);
kDatabase
.child('profile')
.child(usermodel.userId)
.child('followingList')
.set(usermodel.followingList);
cprint('user added to following list',event: 'add_follow');
notifyListeners();
} catch (error) {
cprint(error,errorIn: 'followUser');
}
}
/// Trigger when logged-in user's profile change or updated
/// Firebase event callback for profile update
void _onProfileChanged(Event event) {
if (event.snapshot != null) {
final updatedUser = User.fromJson(event.snapshot.value);
if (updatedUser.userId == user.uid) {
_usermodel = updatedUser;
}
cprint('User Updated');
notifyListeners();
}
}
}
这些是我做的日志
Flutter clean
之后
Flutter run --release
日志:
I/Flutter (13941):
E/Flutter (13941): [ERROR:Flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: NoSuchMethodError: The method 'getCurrentUser' was called on null.
E/Flutter (13941): Receiver: null
E/Flutter (13941): Tried calling: getCurrentUser()
E/Flutter (13941): #0 _SplashPageState.timer.<anonymous closure> (package:boots/page/common/splash.dart:31)
E/Flutter (13941): #1 _rootRunUnary (dart:async/zone.dart:1198)
E/Flutter (13941): #2 _CustomZone.runUnary (dart:async/zone.dart:1100)
E/Flutter (13941): #3 _FutureListener.handleValue (dart:async/future_impl.dart:143)
E/Flutter (13941): #4 Future._propagatetoListeners.handleValueCallback (dart:async/future_impl.dart:696)
E/Flutter (13941): #5 Future._propagatetoListeners (dart:async/future_impl.dart:725)
E/Flutter (13941): #6 Future._complete (dart:async/future_impl.dart:519)
E/Flutter (13941): #7 new Future.delayed.<anonymous closure> (dart:async/future.dart:323)
E/Flutter (13941): #8 _rootRun (dart:async/zone.dart:1182)
E/Flutter (13941): #9 _CustomZone.run (dart:async/zone.dart:1093)
E/Flutter (13941): #10 _CustomZone.runGuarded (dart:async/zone.dart:997)
E/Flutter (13941): #11 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037)
E/Flutter (13941): #12 _rootRun (dart:async/zone.dart:1190)
E/Flutter (13941): #13 _CustomZone.run (dart:async/zone.dart:1093)
E/Flutter (13941): #14 _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:1021)
E/Flutter (13941): #15 TickerFuture.whenCompleteOrCancel.thunk (package:Flutter/src/scheduler/ticker.dart:399)
E/Flutter (13941): #16 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:397)
E/Flutter (13941): #17 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:428)
E/Flutter (13941): #18 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168)
E/Flutter (13941):
由于我的应用程序因此无法再启动,因此我想纠正此问题。感谢所有帮助!
解决方法
结果是我的更新导致需要添加新的firebase依赖项。
在pubspec.yaml中,必须添加:
df <- structure(list(organisms = structure(1:3,.Label = c("A","B","C"),class = "factor"),indicator_value = c(0.98,0.98,0.98
),R_G1 = c(1,0.05,0.02),p_G1 = c(0.05,NA,R_G2 = c(0.2,0.1,0.07),p_G2 = c(5L,3L,NA),R_G3 = c(0.09,0.09,0.2),p_G3 = c(0.02,0.04,0.02)),class = "data.frame",row.names = c(NA,-3L))
df
#> organisms indicator_value R_G1 p_G1 R_G2 p_G2 R_G3 p_G3
#> 1 A 0.98 1.00 0.05 0.20 5 0.09 0.02
#> 2 B 0.98 0.05 NA 0.10 3 0.09 0.04
#> 3 C 0.98 0.02 0.02 0.07 NA 0.20 0.02
主要是必须添加
firebase_core: ^0.5.2
就在
之前await Firebase.initializeApp();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。