flutter - 未处理的异常:NoSuchMethodError:在 null 上调用了方法“[]”。尝试调用:[]("username")
问题描述
Bonjour tout le monde,
我的控制台中有此错误消息,我搜索了几天没有找到答案。
错误消息:未处理的异常:NoSuchMethodError:在 null 上调用了方法“[]”。尝试调用:
你能帮助我吗?这是我的代码:
final auth = FirebaseAuth.instance;
final googleSignIn = GoogleSignIn();
final ref = FirebaseFirestore.instance.collection('Users');
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
Users currentUserModel;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized(); // after upgrading flutter this is now necessary
await Firebase.initializeApp();
// enable timestamps in firebase
runApp(MyApp());
}
Future<Null> _ensureLoggedIn(BuildContext context) async {
GoogleSignInAccount user = googleSignIn.currentUser;
if (user == null) {
user = await googleSignIn.signInSilently();
}
if (user == null) {
await googleSignIn.signIn();
await tryCreateUserRecord(context);
}
if (await auth.currentUser == null) {
final GoogleSignInAccount googleUser = await googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth = await googleUser
.authentication;
final AuthCredential credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
await auth.signInWithCredential(credential);
}
}
Future<Null> _silentLogin(BuildContext context) async {
GoogleSignInAccount user = googleSignIn.currentUser;
if (user == null) {
user = await googleSignIn.signInSilently();
await tryCreateUserRecord(context);
}
if (await auth.currentUser == null && user != null) {
final GoogleSignInAccount googleUser = await googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth = await googleUser
.authentication;
final AuthCredential credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
await auth.signInWithCredential(credential);
}
}
Future<Null> _setUpNotifications() async {
if (Platform.isAndroid) {
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print('on message $message');
},
onResume: (Map<String, dynamic> message) async {
print('on resume $message');
},
onLaunch: (Map<String, dynamic> message) async {
print('on launch $message');
},
);
_firebaseMessaging.getToken().then((token) {
print("Firebase Messaging Token: " + token);
FirebaseFirestore.instance
.collection("Users")
.doc(currentUserModel.id)
.update({"androidNotificationToken": token});
});
}
}
Future<void> tryCreateUserRecord(BuildContext context) async {
GoogleSignInAccount user = googleSignIn.currentUser;
if (user == null) {
return null;
}
DocumentSnapshot userRecord = await ref.doc(user.id).get();
if (userRecord.data == null) {
// no user record exists, time to create
String userName = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Center(
child: Scaffold(
appBar: AppBar(
leading: Container(),
title: Text('Fill out missing data',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold)),
backgroundColor: Colors.white,
),
body: ListView(
children: <Widget>[
Container(
child: CreateAccount(),
),
],
)),
)),
);
if (userName != null || userName.length != 0) {
ref.doc(user.id).set({
"id": user.id,
"username": userName,
"photoUrl": user.photoUrl,
"email": user.email,
"displayName": user.displayName,
"bio": "",
"followers": {},
"following": {},
});
}
userRecord = await ref.doc(user.id).get();
}
currentUserModel = Users.fromDocument(userRecord);
return null;
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MyApp',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or press Run > Flutter Hot Reload in IntelliJ). Notice that the
// counter didn't reset back to zero; the application is not restarted.
primarySwatch: Colors.blue,
buttonColor: Colors.pink,
primaryIconTheme: IconThemeData(color: Colors.black)),
home: HomePage(title: 'Myapp'),
);
}
}
class HomePage extends StatefulWidget {
HomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_HomePageState createState() => _HomePageState();
}
PageController pageController;
class _HomePageState extends State<HomePage> {
int _page = 0;
bool triedSilentLogin = false;
bool setupNotifications = false;
Scaffold buildLoginPage() {
return Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.only(top: 240.0),
child: Column(
children: <Widget>[
Text(
'MyApp',
style: TextStyle(
fontSize: 60.0,
fontFamily: "Billabong",
color: Colors.black),
),
Padding(padding: const EdgeInsets.only(bottom: 100.0)),
GestureDetector(
onTap: login,
child: Image.asset(
"assets/images/google_signin_button.png",
width: 225.0,
),
)
],
),
),
),
);
}
@override
Widget build(BuildContext context) {
if (triedSilentLogin == false) {
silentLogin(context);
}
if (setupNotifications == false && currentUserModel != null) {
setUpNotifications();
}
return (googleSignIn.currentUser == null || currentUserModel == null)
? buildLoginPage()
: Scaffold(
body: PageView(
children: [
Container(
color: Colors.white,
child: Feed(),
),
Container(color: Colors.white, child: SearchPage()),
Container(
color: Colors.white,
child: Uploader(),
),
Container(
color: Colors.white, child: ActivityFeedPage()),
Container(
color: Colors.white,
child: ProfilePage(
userId: googleSignIn.currentUser.id,
)),
],
controller: pageController,
physics: NeverScrollableScrollPhysics(),
onPageChanged: onPageChanged,
),
bottomNavigationBar: CupertinoTabBar(
backgroundColor: Colors.white,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home,
color: (_page == 0) ? Colors.black : Colors.grey),
title: Container(height: 0.0),
backgroundColor: Colors.white),
BottomNavigationBarItem(
icon: Icon(Icons.search,
color: (_page == 1) ? Colors.black : Colors.grey),
title: Container(height: 0.0),
backgroundColor: Colors.white),
BottomNavigationBarItem(
icon: Icon(Icons.add_circle,
color: (_page == 2) ? Colors.black : Colors.grey),
title: Container(height: 0.0),
backgroundColor: Colors.white),
BottomNavigationBarItem(
icon: Icon(Icons.star,
color: (_page == 3) ? Colors.black : Colors.grey),
title: Container(height: 0.0),
backgroundColor: Colors.white),
BottomNavigationBarItem(
icon: Icon(Icons.person,
color: (_page == 4) ? Colors.black : Colors.grey),
title: Container(height: 0.0),
backgroundColor: Colors.white),
],
onTap: navigationTapped,
currentIndex: _page,
),
);
}
void login() async {
await _ensureLoggedIn(context);
setState(() {
triedSilentLogin = true;
});
}
void setUpNotifications() {
_setUpNotifications();
setState(() {
setupNotifications = true;
});
}
void silentLogin(BuildContext context) async {
await _silentLogin(context);
setState(() {
triedSilentLogin = true;
});
}
void navigationTapped(int page) {
//Animating Page
pageController.jumpToPage(page);
}
void onPageChanged(int page) {
setState(() {
this._page = page;
});
}
@override
void initState() {
super.initState();
pageController = PageController();
}
@override
void dispose() {
super.dispose();
pageController.dispose();
}
}
和我的 user.dart:
class Users {
final String email;
final String id;
final String photoUrl;
final String username;
final String displayName;
final String bio;
final Map followers;
final Map following;
const Users(
{this.username,
this.id,
this.photoUrl,
this.email,
this.displayName,
this.bio,
this.followers,
this.following});
factory Users.fromDocument(DocumentSnapshot doc) {
return Users(
id: doc.id,
username: doc.data()['username'],
email: doc.data()['email'],
photoUrl: doc.data()['photoUrl'],
displayName: doc.data()['displayName'],
bio: doc.data()['bio'],
followers: doc.data()['followers'],
following: doc.data()['following'],
);
}
}
我认为问题出在 user.dart 文件中的工厂,但我不确定......我还在寻找......谢谢你的帮助
解决方案
推荐阅读
- django - Django [创建具有特定权限的用户]
- java - 在 Java 代码中输入小数时出现编译错误
- java - 是否可以通过球衣获取带有 Serveur 文件的 HTML 选择?
- vaadin - 如何获取vaadin-grid的行索引
- python-2.7 - 使用 if 语句根据另一个数据框中的值在数据框中创建一列
- sql - UniGrid 绑定
- jquery - 仅对 1200 像素及以上的屏幕启用悬停效果
- python - 仪表板页面打不开
- php - 在 url Laravel 5.5 中仅显示产品名称
- powershell - 将 Get-Childitem 的输出组合到 [System.Reflection.Assembly]::LoadFrom(...)