flutter聊天应用程序firebase auth和getTream.io函数
我目前正在关注本教程( https://wwww.youtube.com/watch? )关于如何创建flutter聊天应用程序。我面临的问题是,每当我注册一个新帐户时,都会显示错误,并且不会将我引向主屏幕。但是,如果我登录或重新启动,我将能够进入主屏幕。我有以下日志,但不确定出了什么问题。任何帮助将不胜感激。源代码可在此处找到: https://github.com/hayesgordon/chatter error error
firebase_functions/unauthenticated] UNAUTHENTICATED<…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m<…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m#0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:607:7)<…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m#1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:167:18)<…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m<asynchronous suspension><…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m#2 MethodChannelHttpsCallable.call (package:cloud_functions_platform_interface/src/method_channel/method_channel_https_callable.dart:23:24)<…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m<asynchronous suspension><…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m#3 HttpsCallable.call (package:cloud_functions/src/https_callable.dart:49:37)<…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m<asynchronous suspension><…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m#4 _SignUpScreenState._signUp (package:ibchat/screens/sign_up_screen.dart:368:25)<…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m<asynchronous suspension><…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m<…>
flutter: \^[[38;5;196m├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄<…>
flutter: \^[[38;5;196m│ #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:607:7)<…>
flutter: \^[[38;5;196m│ #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:167:18)<…>
flutter: \^[[38;5;196m│ #2 <asynchronous suspension><…>
flutter: \^[[38;5;196m│ #3 MethodChannelHttpsCallable.call (package:cloud_functions_platform_interface/src/method_channel/method_channel_https_callable.dart:23:24)<…>
flutter: \^[[38;5;196m│ #4 <asynchronous suspension><…>
flutter: \^[[38;5;196m│ #5 HttpsCallable.call (package:cloud_functions/src/https_callable.dart:49:37)<…>
flutter: \^[[38;5;196m│ #6 <asynchronous suspension><…>
flutter: \^[[38;5;196m│ #7 _SignUpScreenState._signUp (package:ibchat/screens/sign_up_screen.dart:368:25)<…>
flutter: \^[[38;5;196m├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄<…>
flutter: \^[[38;5;196m│ ⛔ Sign up error<…>
flutter: \^[[38;5;196m└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────<…>
error:不:不要:不要在异步差距上使用buildContexts。 (和 **)
Future<void> _signUp() async {
if (_formKey.currentState!.validate()) {
setState(() {
_loading = true;
});
try {
// Authenticate with Firebase
final creds =
await firebase.FirebaseAuth.instance.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
);
final user = creds.user;
if (user == null) {
**ScaffoldMessenger.of(context)**.showSnackBar(
const SnackBar(content: Text('Member not found')),
);
return;
}
// Set Firebase display name and profile picture
List<Future<void>> futures = [
if (_profilePictureController.text.isNotEmpty)
creds.user!.updatePhotoURL(_profilePictureController.text),
creds.user!.updateDisplayName(_nameController.text),
];
await Future.wait(futures);
// Create Stream user and get token using Firebase Functions
final callable = functions.httpsCallable('createStreamUserAndGetToken');
final results = await callable();
// Connect user to Stream and set user data
final client = **StreamChatCore.of(context)**.client;
await client.connectUser(
User(
image: _profilePictureController.text,
id: creds.user!.uid,
name: _nameController.text,
/*designation: _designationController.text,
company: _companyController.text,*/
),
results.data,
);
// Navigate to home screen
await **Navigator.of(context)**.pushReplacement(HomeScreen.route);
} on firebase.FirebaseAuthException catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.red, content: Text(e.message ?? 'Auth error')),
);
} catch (e, st) {
logger.e('Sign up error', e, st);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(backgroundColor: Colors.red, content: Text('An error occured')),
);
}
setState(() {
_loading = false;
});
}
}
Future<void> _signIn() async {
if (_formKey.currentState!.validate()) {
setState(() {
_loading = true;
});
try {
// Authenticate with Firebase
final creds =
await firebase.FirebaseAuth.instance.signInWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
);
final user = creds.user;
if (user == null) {
**ScaffoldMessenger.of(context)**.showSnackBar(
const SnackBar(content: Text('Member not found')),
);
return;
}
// Get Stream user token from Firebase Functions
final callable = functions.httpsCallable('getStreamUserToken');
final results = await callable();
// Connnect stream user
final client = **StreamChatCore.of(context)**.client;
await client.connectUser(
User(id: creds.user!.uid),
results.data,
);
// Navigate to home screen
await **Navigator.of(context)**.pushReplacement(HomeScreen.route);
} on firebase.FirebaseAuthException catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.red,
content: Text(e.message ?? 'Authentication error')),
);
} catch (e, st) {
logger.e('Sign in error, ', e, st);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
backgroundColor: Colors.red, content: Text('Error occured')),
);
}
setState(() {
_loading = false;
});
}
}
Future<void> _handleAuthenticatedState() async {
final auth = firebase.FirebaseAuth.instance;
if (!mounted) {
return;
}
listener = auth.authStateChanges().listen((user) async {
if (user != null) {
// get Stream user token
final callable =
FirebaseFunctions.instance.httpsCallable('getStreamUserToken');
final results = await Future.wait([
callable(),
// delay to show loading indicator
Future.delayed(const Duration(milliseconds: 700)),
]);
// connect Stream user
final client = **StreamChatCore.of(context)**.client;
await client.connectUser(
User(id: user.uid),
results[0]!.data,
);
// authenticated
**Navigator.of(context)**.pushReplacement(HomeScreen.route);
} else {
// delay to show loading indicator
await Future.delayed(const Duration(milliseconds: 700));
// not authenticated
**Navigator.of(context)**.pushReplacement(SignInScreen.route);
}
});
}
Future<void> _signOut() async {
setState(() {
_loading = true;
});
try {
await StreamChatCore.of(context).client.disconnectUser();
await firebase.FirebaseAuth.instance.signOut();
**Navigator.of(context)**.pushReplacement(SplashScreen.route);
} on Exception catch (e, st) {
logger.e('Could not sign out', e, st);
setState(() {
_loading = false;
});
}
}
i am currently following this tutorial (https://www.youtube.com/watch?v=y6OlrO3Bzag) on how to create a flutter chat app. the problem that i am facing is that whenever i sign up a new account, it will display an error has occurred and doesn't direct me to the home screen. however, if i sign in or hot restart, i will be able to go to the home screen. i have the logs below but am not sure what is going wrong. any help would be greatly appreciated. the source code is found here: https://github.com/HayesGordon/chatter
firebase_functions/unauthenticated] UNAUTHENTICATED<…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m<…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m#0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:607:7)<…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m#1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:167:18)<…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m<asynchronous suspension><…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m#2 MethodChannelHttpsCallable.call (package:cloud_functions_platform_interface/src/method_channel/method_channel_https_callable.dart:23:24)<…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m<asynchronous suspension><…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m#3 HttpsCallable.call (package:cloud_functions/src/https_callable.dart:49:37)<…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m<asynchronous suspension><…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m#4 _SignUpScreenState._signUp (package:ibchat/screens/sign_up_screen.dart:368:25)<…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m<asynchronous suspension><…>
flutter: \^[[38;5;196m│ \^[[0m\^[[39m\^[[48;5;196m<…>
flutter: \^[[38;5;196m├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄<…>
flutter: \^[[38;5;196m│ #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:607:7)<…>
flutter: \^[[38;5;196m│ #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:167:18)<…>
flutter: \^[[38;5;196m│ #2 <asynchronous suspension><…>
flutter: \^[[38;5;196m│ #3 MethodChannelHttpsCallable.call (package:cloud_functions_platform_interface/src/method_channel/method_channel_https_callable.dart:23:24)<…>
flutter: \^[[38;5;196m│ #4 <asynchronous suspension><…>
flutter: \^[[38;5;196m│ #5 HttpsCallable.call (package:cloud_functions/src/https_callable.dart:49:37)<…>
flutter: \^[[38;5;196m│ #6 <asynchronous suspension><…>
flutter: \^[[38;5;196m│ #7 _SignUpScreenState._signUp (package:ibchat/screens/sign_up_screen.dart:368:25)<…>
flutter: \^[[38;5;196m├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄<…>
flutter: \^[[38;5;196m│ ⛔ Sign up error<…>
flutter: \^[[38;5;196m└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────<…>
Error: Do not use BuildContexts across async gaps.
(with **)
Future<void> _signUp() async {
if (_formKey.currentState!.validate()) {
setState(() {
_loading = true;
});
try {
// Authenticate with Firebase
final creds =
await firebase.FirebaseAuth.instance.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
);
final user = creds.user;
if (user == null) {
**ScaffoldMessenger.of(context)**.showSnackBar(
const SnackBar(content: Text('Member not found')),
);
return;
}
// Set Firebase display name and profile picture
List<Future<void>> futures = [
if (_profilePictureController.text.isNotEmpty)
creds.user!.updatePhotoURL(_profilePictureController.text),
creds.user!.updateDisplayName(_nameController.text),
];
await Future.wait(futures);
// Create Stream user and get token using Firebase Functions
final callable = functions.httpsCallable('createStreamUserAndGetToken');
final results = await callable();
// Connect user to Stream and set user data
final client = **StreamChatCore.of(context)**.client;
await client.connectUser(
User(
image: _profilePictureController.text,
id: creds.user!.uid,
name: _nameController.text,
/*designation: _designationController.text,
company: _companyController.text,*/
),
results.data,
);
// Navigate to home screen
await **Navigator.of(context)**.pushReplacement(HomeScreen.route);
} on firebase.FirebaseAuthException catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.red, content: Text(e.message ?? 'Auth error')),
);
} catch (e, st) {
logger.e('Sign up error', e, st);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(backgroundColor: Colors.red, content: Text('An error occured')),
);
}
setState(() {
_loading = false;
});
}
}
Future<void> _signIn() async {
if (_formKey.currentState!.validate()) {
setState(() {
_loading = true;
});
try {
// Authenticate with Firebase
final creds =
await firebase.FirebaseAuth.instance.signInWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
);
final user = creds.user;
if (user == null) {
**ScaffoldMessenger.of(context)**.showSnackBar(
const SnackBar(content: Text('Member not found')),
);
return;
}
// Get Stream user token from Firebase Functions
final callable = functions.httpsCallable('getStreamUserToken');
final results = await callable();
// Connnect stream user
final client = **StreamChatCore.of(context)**.client;
await client.connectUser(
User(id: creds.user!.uid),
results.data,
);
// Navigate to home screen
await **Navigator.of(context)**.pushReplacement(HomeScreen.route);
} on firebase.FirebaseAuthException catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.red,
content: Text(e.message ?? 'Authentication error')),
);
} catch (e, st) {
logger.e('Sign in error, ', e, st);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
backgroundColor: Colors.red, content: Text('Error occured')),
);
}
setState(() {
_loading = false;
});
}
}
Future<void> _handleAuthenticatedState() async {
final auth = firebase.FirebaseAuth.instance;
if (!mounted) {
return;
}
listener = auth.authStateChanges().listen((user) async {
if (user != null) {
// get Stream user token
final callable =
FirebaseFunctions.instance.httpsCallable('getStreamUserToken');
final results = await Future.wait([
callable(),
// delay to show loading indicator
Future.delayed(const Duration(milliseconds: 700)),
]);
// connect Stream user
final client = **StreamChatCore.of(context)**.client;
await client.connectUser(
User(id: user.uid),
results[0]!.data,
);
// authenticated
**Navigator.of(context)**.pushReplacement(HomeScreen.route);
} else {
// delay to show loading indicator
await Future.delayed(const Duration(milliseconds: 700));
// not authenticated
**Navigator.of(context)**.pushReplacement(SignInScreen.route);
}
});
}
Future<void> _signOut() async {
setState(() {
_loading = true;
});
try {
await StreamChatCore.of(context).client.disconnectUser();
await firebase.FirebaseAuth.instance.signOut();
**Navigator.of(context)**.pushReplacement(SplashScreen.route);
} on Exception catch (e, st) {
logger.e('Could not sign out', e, st);
setState(() {
_loading = false;
});
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我是您上面链接的视频教程的作者。
对于任何阅读本文以及对Firebase Auth + Stream感兴趣的人,请参阅我们的更新的扑波指南: https://getStream.io/chat/docs/sdk/flutter/guides/guides/token_generation_with_firebase/
流现在有一个firebase扩展名,可以轻松管理繁重的举重。因此,上面的视频需要更新版本。
回答您的问题:
似乎即使未对firebase用户进行身份验证,也正在发生“ createStreamuserandgetToken”云功能。我看到您在此处的回购中为此创建了一张票: https://github.com/github.com/ /chatter/eslove/8
所以让我们在那里进一步讨论。
关于“跨异步差距”的限制问题noreferrer“> https://dart-lang.github.io/linter/lints/use_build_context_synchronase.html
I'm the author of the video tutorial you linked above.
For anyone reading this and who is interested in Firebase Auth + Stream, please see our updated Flutter guide: https://getstream.io/chat/docs/sdk/flutter/guides/token_generation_with_firebase/
Stream now has a Firebase extension to easily manage the heavy lifting for you. So the video above needs an updated version.
To answer your question:
It seems like the call to "createStreamUserAndGetToken" cloud function is happening even though the Firebase user is not authenticated. I see you created a ticket for this on the repo here: https://github.com/HayesGordon/chatter/issues/8
So let's discuss it further there.
With regards to your limiting issue for "BuildContexts across async gaps" see here: https://dart-lang.github.io/linter/lints/use_build_context_synchronously.html