首先,首先要感谢,我尝试创建一个应用程序,并尝试将其与flutter一起使用,首先,我在应用程序内部管理了用户的状态登录,为此,我按照本指南https://fireship.io/lessons/flutter-firebase-google-oauth-firestore/的要求使用该应用程序预期在登录页面中使用Facebook登录(observable发出新值,并使用StreamBuilder创建相应的小部件,一切正常!),但是当我按下返回按钮到其他页面并再次输入登录页面时,与StreamBuilder关联的流小部件返回null,从而再次显示formLogin(要注册的表单)小部件,而不是个人资料小部件(小部件,以显示用户信息),或者我错误地使用了streamBuilder,任何建议都得到了很好的接受。
我输入了代码
再次感谢
登录小部件(用于管理登录和用户信息的小部件)和AuthService(用于登录的逻辑)
ProfilePage({Key key}) : super(key: key);
_ProfilePageState createState() => _ProfilePageState();
}
class _ProfilePageState extends State<ProfilePage>
with TickerProviderStateMixin {
var opacity = true;
AnimationController _controller;
Animation<double> _animation;
bool _loading = false;
final GlobalKey<FormState> _formKeyLogin = GlobalKey<FormState>();
final GlobalKey<FormState> _formKeyLogup = GlobalKey<FormState>();
final PageController _pageController = PageController();
int _typeForm = 0;
// int currentPage = 1;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this, duration: Duration(milliseconds: 1500));
_animation = CurvedAnimation(
parent: _controller,
curve: Curves.decelerate,
);
_controller.forward();
authService.loading.listen((state) => setState(() => _loading = state));
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
children: <Widget>[
StreamBuilder(
stream: authService.profile,
builder: (context, snapshot) {
if (snapshot.hasData) {
User user = User.mapFromMap(snapshot.data);
return new FormProfile(loading: _loading, user: user);
} else {
return new FormLogin(
animation: _animation,
loading: _loading,
pageController: _pageController,
formKeyLogin: _formKeyLogin,
formKeyLogup: _formKeyLogup);
}
},
)
],
),
),
);
}
}
class AuthService {
final GoogleSignIn _googleAuth = GoogleSignIn();
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
final Firestore _firestore = Firestore.instance;
bool isAdmin = false;
Observable<FirebaseUser> user; //FirebaseUser instance
Observable<Map<String, dynamic>> profile; //database's user info
PublishSubject loading = PublishSubject();
AuthService() {
user = Observable(_firebaseAuth.onAuthStateChanged);
profile = user.switchMap((FirebaseUser u) {
if (u != null) {
return _firestore
.collection("users")
.document(u.uid)
.snapshots()
.map((snap) => snap.data);
} else {
return Observable.just(null);
}
});
}
Future<FirebaseUser> facebookLogin() async {
loading.add(true);
final facebookLogin = FacebookLogin();
final result = await facebookLogin.logInWithReadPermissions(['email']);
FirebaseUser user;
switch (result.status) {
case FacebookLoginStatus.loggedIn:
final AuthCredential credential = FacebookAuthProvider.getCredential(
accessToken: result.accessToken.token);
try {
user = await _firebaseAuth.signInWithCredential(credential);
await validateAccount(user);
updateUserData(user);
} on PlatformException catch (e) {
switch (e.code) {
case Strings.AUTH_CONST_ERROR_INVALID_CREDENTIAL:
Utilities.showToast(
Strings.AUTH_CONST_ERROR_INVALID_CREDENTIAL_MSG,
Toast.LENGTH_LONG,
2);
break;
case Strings.AUTH_CONST_ERROR_USER_DISABLED:
Utilities.showToast(Strings.AUTH_CONST_ERROR_USER_DISABLED_MSG,
Toast.LENGTH_LONG, 2);
break;
case Strings
.AUTH_CONST_ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL:
Utilities.showToast(
Strings
.AUTH_CONST_ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL_MSG,
Toast.LENGTH_LONG,
2);
break;
case Strings.AUTH_CONST_ERROR_OPERATION_NOT_ALLOWED:
Utilities.showToast(
Strings.AUTH_CONST_ERROR_OPERATION_NOT_ALLOWED_MSG,
Toast.LENGTH_LONG,
2);
break;
case Strings.AUTH_CONST_ERROR_INVALID_ACTION_CODE:
Utilities.showToast(
Strings.AUTH_CONST_ERROR_INVALID_ACTION_CODE_MSG,
Toast.LENGTH_LONG,
2);
break;
default:
Utilities.showToast(Strings.AUTH_CONST_ERROR_GENERAL_CODE_MSG,
Toast.LENGTH_LONG, 2);
}
}
break;
case FacebookLoginStatus.cancelledByUser:
break;
case FacebookLoginStatus.error:
Utilities.showToast(result.errorMessage, Toast.LENGTH_SHORT, 2);
//_showErrorOnUI(result.errorMessage);
break;
}
loading.add(false);
return user;
}
final AuthService authService = AuthService();
答案 0 :(得分:1)
您的问题可能是由于您使用的是Observables而不是Streams,或者对于您的加载对象而言,是PublishSubject。如此处rxdart Observable class所述,Observables是单一订阅-根据您的描述,您已经从该订阅的应用程序其他位置接收到数据。
考虑使用多订阅的广播流(Observable asBroadcastStream),另一个PublishSubject(本质上是广播),或者如果您不喜欢使用Observables,则可以将其替换为标准Dart Streams ,在这种情况下,您的界面可能如下所示:
BehaviorSubject<FirebaseUser> _user; //Or PublishSubject
Sink<Map<String, dynamic>> get inProfile => _user.sink; // call .add() to inProfile to add new data
Stream<Map<String, dynamic>> get outProfile => _user.stream; // attach this to your Streambuilder output