我正在这个应用程序上工作,我使用谷歌和fire商店登录用户。如果用户已经存在并登录。我得到的错误是displayName在null上被调用,但当我热加载应用程序时,应用程序工作得很好。下面是代码
```
final GoogleSignIn googleSignIn = GoogleSignIn();
final userRef = FirebaseFirestore.instance.collection("users");
final DateTime timestamp = DateTime.now();
MyUser currentUser;
bool isAuth = false;
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
void toggleDrawer() async {
if (_scaffoldKey.currentState.isDrawerOpen) {
_scaffoldKey.currentState.openEndDrawer();
} else {
_scaffoldKey.currentState.openDrawer();
}
}
int currentIndex = 0;
List<Widget> listofPages = [
Home(),
MyOrders(),
Saved(),
Offers(),
Refer(),
];
Widget currentScreen = Home();
String currentTitle = "gazzUp";
PageController pageController;
final PageStorageBucket bucket = PageStorageBucket();
var phoneNumber;
class CheckAuth extends StatefulWidget {
@override
_CheckAuthState createState() => _CheckAuthState();
}
class _CheckAuthState extends State<CheckAuth> {
@override
void dispose() {
pageController.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
pageController = PageController(initialPage: 1);
googleSignIn.onCurrentUserChanged.listen(
(account) {
handleGoogleSignIn(account);
},
onError: (err) {
EasyLoading.showToast("Error Signing In: $err");
},
);
googleSignIn.signInSilently(suppressErrors: false).then((account) {
handleGoogleSignIn(account);
}).catchError((err) {
print("Error Signing In: $err");
});
}
handleGoogleSignIn(account) {
if (account != null) {
createGoogleUserInFirestore();
setState(() {
isAuth = true;
});
} else {
setState(() {
isAuth = false;
});
}
}
createGoogleUserInFirestore() async {
// 1) Check if User Exists using UID
final GoogleSignInAccount user = googleSignIn.currentUser;
DocumentSnapshot doc = await userRef.doc(user.id).get();
// 2) If User dowsn't exist, Take them to create account page
if (!doc.exists) {
final number = await Navigator.push(
context, MaterialPageRoute(builder: (context) => GetPhoneNumber()));
// final email = await Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => RegistrationScreen(),
// ));
// 3) Get details from Create Account Page, Use them to make new user document in Users collection
userRef.doc(user.id).set({
"id": user.id,
"e-mail": user.email,
"photoUrl": user.photoUrl,
"name": user.displayName,
"timeStamp": timestamp,
"phoneNumber": number,
});
}
doc = await userRef.doc(user.id).get();
currentUser = MyUser.fromDocument(doc);
print(currentUser);
print(currentUser.email);
// 3) Get details from Create Account Page, Use them to make new user document in Users collection
}
googleLogIn() async {
EasyLoading.show(status: "Signing You In");
await googleSignIn.signIn();
EasyLoading.dismiss();
// if (isAuth = false) {
// EasyLoading.showToast("Couldn't Sign You In",
// toastPosition: EasyLoadingToastPosition.bottom);
// } else {
// EasyLoading.showToast("Welcome",
// toastPosition: EasyLoadingToastPosition.bottom);
// }
}
googleLogOut() async {
EasyLoading.show(status: "Signing You Out");
await googleSignIn.signOut();
EasyLoading.dismiss();
}
@override
Widget build(BuildContext context) {
return isAuth ? mainView() : logInScreen();
}
Scaffold logInScreen() {
return Scaffold(
body: SingleChildScrollView(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/bg.png"),
fit: BoxFit.cover,
),
),
height: MediaQuery.of(context).size.height,
padding: EdgeInsets.symmetric(
horizontal: 10.0, vertical: MediaQuery.of(context).padding.top),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
RawMaterialButton(
constraints: BoxConstraints(),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
),
onPressed: () {},
child: Padding(
padding: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"Skip for Now",
style: TextStyle(
color: Colors.deepOrange[900],
fontWeight: FontWeight.w600,
fontSize: 13.0,
),
),
Icon(
Icons.arrow_forward_ios,
color: Colors.deepOrange[900],
size: 12,
)
],
),
),
)
],
),
Text(
"gazzUp",
style: TextStyle(
color: Colors.deepOrange,
fontSize: 53,
fontFamily: "Cocogoose"),
),
SizedBox(
height: 100.0,
),
Container(
child: KMainTextField(
label: "Enter Your Phone Number",
inputType: TextInputType.number,
obscureText: false,
leading: Icon(Icons.phone),
validator: (val) {
if (val.isEmpty) {
return "Can't be Empty";
} else if (val.length < 10 || val.length > 10) {
return "Enter a Valid Phone Number";
}
return null;
},
onChanged: (val) {
setState(() {
phoneNumber = val;
});
},
),
),
// SizedBox(
// height: 30.0,
// ),
RaisedButton(
color: Colors.deepOrange,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
padding: EdgeInsets.all(15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Send OTP",
style: TextStyle(
color: Colors.white,
fontFamily: "Cocogoose",
fontSize: 18.0),
),
Icon(
Icons.arrow_forward_ios,
color: Colors.white,
)
],
),
onPressed: () {},
),
SizedBox(
height: 120.0,
),
GoogleAuthButton(
borderColor: Colors.white,
textStyle: TextStyle(fontSize: 14),
elevation: 5.0,
borderRadius: 50.0,
onPressed: () {
try {
googleLogIn();
} catch (e) {
EasyLoading.showToast(e.toString());
}
},
),
SizedBox(
height: 20.0,
),
],
),
),
),
);
}
Scaffold mainView() {
return Scaffold(
backgroundColor: Colors.deepOrange,
key: _scaffoldKey,
// appBar: AppBar(
// leading: currentIndex == 0
// ? Builder(
// builder: (BuildContext context) {
// return IconButton(
// icon: Icon(Icons.menu),
// onPressed: () {
// _scaffoldKey.currentState.openDrawer();
// },
// );
// },
// )
// : SizedBox(
// width: 0,
// ),
// elevation: 10.0,
// title: Transform(
// transform: currentIndex == 0
// ? Matrix4.translationValues(0.0, 0.0, 0.0)
// : Matrix4.translationValues(-50.0, 0.0, 0.0),
// child: Text(
// currentTitle,
// style: TextStyle(
// color: Colors.white,
// fontFamily: currentIndex == 0 ? "Cocogoose" : "SegoeUi",
// fontSize: currentIndex == 0 ? 30.0 : 22.0,
// fontWeight: currentIndex == 0 ? null : FontWeight.bold,
// ),
// ),
// ),
// centerTitle: currentIndex == 0 ? true : false,
// actions: [
// currentIndex == 0
// ? Container(
// padding: EdgeInsets.all(12.0),
// child: Image(
// image: AssetImage("assets/images/qrCode.png"),
// fit: BoxFit.cover,
// ),
// )
// : Padding(
// padding: const EdgeInsets.symmetric(horizontal: 15.0),
// child: Icon(
// Icons.notifications_none_outlined,
// size: 25,
// ),
// ),
// ],
// ),
appBar: PreferredSize(
child: Center(
child: Container(
margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black26, offset: Offset(0, 4), blurRadius: 6)
],
gradient: RadialGradient(
center: Alignment.topLeft,
radius: 4.0,
colors: [
Colors.deepOrange,
Colors.red,
Colors.pink,
],
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
onTap: () {
toggleDrawer();
},
child: Center(
child: Container(
padding: EdgeInsets.symmetric(
vertical: 10.0, horizontal: 10.0),
child: Icon(
Icons.menu,
size: 30,
color: Colors.white,
),
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"gazzUp",
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontFamily: "Cocogoose"),
),
],
),
// IconButton(
// icon: Icon(
// Icons.qr_code,
// color: Colors.white,
// ),
// onPressed: () {},
// )
GestureDetector(
onTap: () {
Navigator.push(context,
CupertinoPageRoute(builder: (context) => QRPage()));
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: Image(
image: AssetImage("assets/images/qrCode.png"),
height: 30,
width: 30,
),
),
)
],
),
),
),
preferredSize: Size(MediaQuery.of(context).size.width, 60.0),
),
drawer: Drawer(
child: Column(
children: [
UserAccountsDrawerHeader(
decoration: BoxDecoration(
gradient: RadialGradient(
center: Alignment.topLeft,
colors: [
// Colors.orange,
Colors.deepOrange,
Colors.red,
Colors.pink,
],
radius: 2,
),
),
accountName: Text(
currentUser.displayName == null
? "User"
: currentUser.displayName,
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w600,
letterSpacing: 1.0,
fontFamily: "SegoeUi"),
),
accountEmail: Row(
children: [
Row(
children: [
Icon(
Icons.location_on,
color: Colors.white,
size: 10.0,
),
SizedBox(
width: 3.0,
),
Text(
"Delhi",
style: TextStyle(
color: Colors.white,
fontSize: 12.0,
fontWeight: FontWeight.w600),
),
],
),
Container(
margin: EdgeInsets.symmetric(horizontal: 5.0),
height: 10,
width: 0.5,
color: Colors.white,
),
Text(
// currentUser.email != null ? currentUser.email : "No Email",
currentUser.email,
style: TextStyle(fontSize: 12),
),
],
),
currentAccountPicture: CircleAvatar(
backgroundColor: Colors.deepOrange[200],
backgroundImage: NetworkImage(currentUser.photoUrl),
),
),
KListTile(
leading: Icons.list,
title: "List Your Pump",
onTap: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => ListingPage(),
));
toggleDrawer();
},
),
KDivider(),
KListTile(
leading: Icons.thumb_up,
title: "Feedback",
onTap: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => FeedbackPage(),
));
toggleDrawer();
},
),
KListTile(
leading: Icons.contacts,
title: "Contact Us",
),
KListTile(
leading: Icons.help,
title: "Terms and Policies",
),
KDivider(),
KListTile(
leading: Icons.settings,
title: "Settings",
onTap: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => SettingsPage(),
));
toggleDrawer();
},
),
KListTile(
leading: Icons.exit_to_app,
title: "Log Out",
onTap: () {
googleLogOut();
},
),
],
),
),
body: PageStorage(
child: currentScreen,
bucket: bucket,
),
floatingActionButton: Padding(
padding: const EdgeInsets.only(top: 30.0),
child: FloatingActionButton(
backgroundColor: currentIndex == 0 ? Colors.deepOrange : Colors.white,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
child: Icon(Icons.home,
size: 35, color: currentIndex == 0 ? Colors.white : Colors.black),
onPressed: () {
setState(() {
currentIndex = 0;
currentScreen = Home();
currentTitle = "gazzUp";
});
},
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
bottomNavigationBar: Container(
height: 70,
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [BoxShadow(color: Colors.black26, blurRadius: 5)],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
KBottomBarIcon(
currentIndex == 1
? FontAwesomeIcons.solidFileAlt
: FontAwesomeIcons.fileAlt, () {
setState(() {
currentIndex = 1;
currentScreen = MyOrders();
currentTitle = "My Orders";
});
}, "My Orders",
currentIndex == 1 ? Colors.deepOrange : Colors.black),
KBottomBarIcon(
currentIndex == 2
? FontAwesomeIcons.solidHeart
: FontAwesomeIcons.heart, () {
setState(() {
currentIndex = 2;
currentScreen = Saved();
currentTitle = "Saved";
});
}, "Saved", currentIndex == 2 ? Colors.deepOrange : Colors.black),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
),
height: 50,
width: 50,
child: RawMaterialButton(
constraints: BoxConstraints(),
child: Icon(
Icons.home,
size: 40,
color: Colors.white,
),
onPressed: () {},
)),
Container(
padding: EdgeInsets.symmetric(vertical: 10),
child: RawMaterialButton(
splashColor: Colors.white,
highlightColor: Colors.white,
constraints: BoxConstraints(),
onPressed: () {
setState(() {
currentIndex = 3;
currentScreen = Offers();
currentTitle = "Offers";
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image(
image: currentIndex != 3
? AssetImage(
"assets/images/offer.png",
)
: AssetImage("assets/images/solidOffer.png"),
height: 26,
width: 26,
),
Text(
"Offers",
style: TextStyle(fontSize: 9.5, letterSpacing: -.75),
),
],
),
),
),
KBottomBarIcon(
currentIndex == 4
? FontAwesomeIcons.solidHandshake
: FontAwesomeIcons.handshake, () {
setState(() {
currentIndex = 4;
currentScreen = Refer();
currentTitle = "Refer and Earn";
});
}, "Refer & Earn",
currentIndex == 4 ? Colors.deepOrange : Colors.black),
],
),
),
// bottomNavigationBar: CupertinoTabBar(
// backgroundColor: Colors.white,
// currentIndex: pageIndex,
// onTap: onTap,
// items: [
// BottomNavigationBarItem(
// label: "My Orders",
// icon: Icon(
// FontAwesomeIcons.fileAlt,
// ),
// activeIcon: Icon(FontAwesomeIcons.solidFileAlt),
// ),
// BottomNavigationBarItem(
// label: "Saved",
// icon: Icon(FontAwesomeIcons.heart),
// activeIcon: Icon(FontAwesomeIcons.solidHeart),
// ),
// BottomNavigationBarItem(
// icon: Icon(FontAwesomeIcons.trophy, color: Colors.white),
// ),
// BottomNavigationBarItem(
// icon: Icon(
// FontAwesomeIcons.trophy,
// ),
// ),
// BottomNavigationBarItem(
// icon: Icon(FontAwesomeIcons.handshake),
// activeIcon: Icon(FontAwesomeIcons.solidHandshake)),
// ],
// activeColor: Colors.deepOrange,
// ),
);
}
}
```
调试控制台显示这个==============
Launching libmain.dart on POCOPHONE F1 in debug mode...
libmain.dart:1
√ Built buildappoutputsflutter-apkapp-debug.apk.
Connecting to VM Service at ws://127.0.0.1:60201/1xgZZsjBYws=/ws
════════ Exception caught by widgets library ═══════════════════════════════════
The following NoSuchMethodError was thrown building CheckAuth(dirty, dependencies: [MediaQuery], state: _CheckAuthState#4d2e1):
The getter 'displayName' was called on null.
Receiver: null
Tried calling: displayName
The relevant error-causing widget was
CheckAuth
libMainPagesSplashScreen.dart:55
When the exception was thrown, this was the stack
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 _CheckAuthState.mainView
package:trial_1/Services/CheckAuth.dart:440
#2 _CheckAuthState.build
package:trial_1/Services/CheckAuth.dart:156
#3 StatefulElement.build
package:flutter/…/widgets/framework.dart:4744
#4 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4627
...
════════════════════════════════════════════════════════════════════════════════
W/DynamiteModule(20226): Local module descriptor class for providerinstaller not found.
I/DynamiteModule(20226): Considering local module providerinstaller:0 and remote module providerinstaller:0
W/ProviderInstaller(20226): Failed to load providerinstaller module: No acceptable module found. Local version is 0 and remote version is 0.
I/example.trial_(20226): The ClassLoaderContext is a special shared library.
════════ Exception caught by widgets library ═══════════════════════════════════
The getter 'displayName' was called on null.
Receiver: null
Tried calling: displayName
The relevant error-causing widget was
CheckAuth
libMainPagesSplashScreen.dart:55
════════════════════════════════════════════════════════════════════════════════
I/example.trial_(20226): The ClassLoaderContext is a special shared library.
I/TetheringManager(20226): registerTetheringEventCallback:com.example.trial_1
V/NativeCrypto(20226): Registering com/google/android/gms/org/conscrypt/NativeCrypto's 287 native methods...
W/example.trial_(20226): Accessing hidden method Ljava/security/spec/ECParameterSpec;->getCurveName()Ljava/lang/String; (greylist, reflection, allowed)
I/ProviderInstaller(20226): Installed default security provider GmsCore_OpenSSL
W/example.trial_(20226): Accessing hidden field Ljava/net/Socket;->impl:Ljava/net/SocketImpl; (greylist, reflection, allowed)
W/example.trial_(20226): Accessing hidden method Ldalvik/system/CloseGuard;->get()Ldalvik/system/CloseGuard; (greylist,core-platform-api, linking, allowed)
W/example.trial_(20226): Accessing hidden method Ldalvik/system/CloseGuard;->open(Ljava/lang/String;)V (greylist,core-platform-api, linking, allowed)
W/example.trial_(20226): Accessing hidden field Ljava/io/FileDescriptor;->descriptor:I (greylist, JNI, allowed)
W/example.trial_(20226): Accessing hidden method Ljava/security/spec/ECParameterSpec;->setCurveName(Ljava/lang/String;)V (greylist, reflection, allowed)
W/example.trial_(20226): Accessing hidden method Ldalvik/system/BlockGuard;->getThreadPolicy()Ldalvik/system/BlockGuard$Policy; (greylist,core-platform-api, linking, allowed)
W/example.trial_(20226): Accessing hidden method Ldalvik/system/BlockGuard$Policy;->onNetwork()V (greylist, linking, allowed)
I/flutter (20226): Instance of 'MyUser'
I/flutter (20226): manavarora191100@gmail.com
I/flutter (20226): Instance of 'MyUser'
I/flutter (20226): manavarora191100@gmail.com
正如你所看到的用户的实例是显示后和displayName被调用较早,所以我想这是问题,但我不确定如何解决它。
尝试用一个空字符串初始化它,直到数据获取并将其保存在setState()中,它将正常工作
最终解决方案:
增加了一个三进制操作来检查用户是否为空。
accountName: currentUser != null
? Text(
currentUser.displayName,
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w600,
letterSpacing: 1.0,
fontFamily: "SegoeUi"),
)
: Container(
height: 2.0,
width: 40.0,
child: LinearProgressIndicator(
backgroundColor: Colors.white,
),
),
然后调用setState,在这里我打印Username(I。(在这里它终于有了一个值),以便它在UI上更新。
doc = await userRef.doc(user.id).get();
currentUser = MyUser.fromDocument(doc);
print(currentUser);
print(currentUser.email);
setState(() {});