问题描述
我正在使用 Firebase 身份验证创建群聊应用。我的应用程序的流程是让用户注册和登录。一旦用户注册或登录,他/她就会被带到聊天屏幕,在那里他们可以发送消息。登录流程工作正常。但是在创建新用户时,我无法在聊天屏幕上检索用户数据。这是我的代码示例。
这就是我在屏幕之间切换的方式。
Scaffold(
body: StreamBuilder(
builder: (context,snapshot) {
if (snapshot.hasData &&
snapshot.connectionState == ConnectionState.active) {
return ChatScreen();
} else {
return AuthScreen();
}
},stream: FirebaseAuth.instance.authStateChanges()));
class _AuthScreenState extends State<AuthScreen> {
final _auth = FirebaseAuth.instance;
var _isLoading = false;
void _submitAuthForm(
String email,String password,String username,bool isLogin,File f,BuildContext ctx,) async {
UserCredential authResult;
try {
final collection = FirebaseFirestore.instance.collection('users');
var imageUrl = '';
setState(() {
_isLoading = true;
});
if (isLogin) {
authResult = await _auth.signInWithEmailAndPassword(
email: email,password: password,);
} else {
authResult = await _auth.createuserWithEmailAndPassword(
email: email,);
final ref = FirebaseStorage.instance
.ref()
.child('user_image')
.child(authResult.user.uid);
// await ref
// .putFile(f)
// .whenComplete(() async => imageUrl = await ref.getDownloadURL());
await ref.putFile(f);
final url = await ref.getDownloadURL();
collection.doc(authResult.user.uid).set({
'username': username,'email': email,'password': password,'imageFile': url
});
}
} on FirebaseAuthException catch (err) {
String errorMessage = '';
if (err.code == 'weak-password') {
errorMessage = 'The password provided is too weak.';
} else if (err.code == 'email-already-in-use') {
errorMessage = 'The account already exists for that email.';
} else if (err.code == 'user-not-found') {
errorMessage = 'No user found for that email.';
} else if (err.code == 'wrong-password') {
errorMessage = 'Wrong password provided for that user.';
}
Scaffold.of(ctx).showSnackBar(
SnackBar(
content: Text(errorMessage),backgroundColor: Theme.of(ctx).errorColor,),);
setState(() {
_isLoading=false;
});
} on PlatformException catch (err) {
var message = 'An error occurred,pelase check your credentials!';
if (err.message != null) {
message = err.message;
}
Scaffold.of(ctx).showSnackBar(
SnackBar(
content: Text(message),);
setState(() {
_isLoading = false;
});
} catch (err) {
setState(() {
_isLoading = false;
});
if (_isLoading == false) {
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Theme.of(context).errorColor,content: Text(err.toString()),));
}
}
}
Future<User> getUserByUid(String uid) async {
final doc = await collection.doc(uid).get();
return User.fromJSON(doc.data());
}
这个负责在聊天屏幕上显示数据。
class ChatScreen extends StatefulWidget {
@override
_ChatScreenState createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
var future;
@override
void initState() {
super.initState();
future= FirebaseService()
.getUserByUid(FirebaseAuth.instance.currentUser.uid);
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _user,builder: (context,snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
return Scaffold(
appBar: AppBar(
toolbarHeight: 70,leading: Container(
margin: EdgeInsets.fromLTRB(10,0),child: InkWell(
onTap: () {
Navigator.of(context)
.pushNamed(SettingsScreen.routeName);
},child: CircleAvatar(
backgroundImage: snapshot.data.imageUrl != null
? NetworkImage(snapshot.data.imageUrl)
: null,)),title: Text(
snapshot.data.username,style: TextStyle(color: Colors.black),backgroundColor: Colors.white,actions: [
IconButton(
color: Colors.white,icon: RadiantGradientMask(
child: FaIcon(FontAwesomeIcons.userFriends)),onpressed: () {
Navigator.push(
context,MaterialPageRoute(
builder: (context) => listofFriends()));
}),IconButton(
//color: Colors.deepPurple,tooltip: 'logout',icon: RadiantGradientMask(
child: FaIcon(FontAwesomeIcons.signOutAlt)),onpressed: () {
FirebaseAuth.instance.signOut();
},)
],elevation: 0.5,centerTitle: true,body: Column(
children: [
Expanded(child: Messages()),NewMessage(),],));
} else {
return Center(child: CircularProgressIndicator());
}
});
} }
这段代码永远不会从 if 块中出来,循环进度指示器永远持续下去。任何帮助将不胜感激,提前致谢。
解决方法
首先避免将你的未来命名为未来。
回答你:
final Future<String> _user; // add prefix 'late' if you are already using sound null safety.
Future<String> _getUserByUID(final var uid) async {
return await FirebaseService().getUserByUid(uid);
}
@override
void initState() {
super.initState();
_user = _getUserByUID(FirebaseAuth.instance.currentUser.uid);
}
[...]
return FutureBuilder(
future: _user,[...]
if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
print('the data is ${snapshot.data}');
return Scaffold(
appBar: AppBar(
[...]
));} else
return Center(child: CircularProgressIndicator());
}
现在应该可以了,如果解决了请告诉我!
编辑:您必须添加 snapshot.hasData
条件,否则您的代码可能会为空;