我正在使用 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,
password: password,
);
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),
backgroundColor: Theme.of(ctx).errorColor,
),
);
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, 0, 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 块中出来,循环进度指示器永远持续下去。任何帮助将不胜感激,提前致谢。
答案 0 :(得分:0)
首先避免将你的未来命名为未来。
回答你:
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
条件,否则您的代码可能会为空;