Когда я нажимаю кнопку «Войти с помощью Google», это дает мне учетные записи для входа в систему. Но после этого, когда я выбираю учетную запись, она загружается и загружается. Следует перейти на другую страницу ... ноНавигатор не выполняет свою работу.
Я делал это с: https://medium.com/@duytq94/building-a-chat-app-with-flutter-and-firebase-from-scratch-9eaa7f41782e
Ссылка на GitHub: https://github.com/duytq94/flutter-chat-demo
1) Это login.dart:
import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:p_chat_2/const.dart';
import 'package:p_chat_2/main.dart';
import 'package:shared_preferences/shared_preferences.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Chat Demo',
theme: ThemeData(
primaryColor: themeColor,
),
home: LoginScreen(title: 'CHAT DEMO'),
debugShowCheckedModeBanner: false,
);
}
}
class LoginScreen extends StatefulWidget {
LoginScreen({Key key, this.title}) : super(key: key);
final String title;
@override
LoginScreenState createState() => LoginScreenState();
}
class LoginScreenState extends State<LoginScreen> {
final GoogleSignIn googleSignIn = GoogleSignIn();
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
SharedPreferences prefs;
bool isLoading = false;
bool isLoggedIn = false;
FirebaseUser currentUser;
@override
void initState() {
super.initState();
isSignedIn();
}
void isSignedIn() async {
this.setState(() {
isLoading = true;
});
prefs = await SharedPreferences.getInstance();
isLoggedIn = await googleSignIn.isSignedIn();
if (isLoggedIn) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MainScreen(currentUserId: prefs.getString('id'))),
);
}
this.setState(() {
isLoading = false;
});
}
Future<Null> handleSignIn() async {
prefs = await SharedPreferences.getInstance();
this.setState(() {
isLoading = true;
});
GoogleSignInAccount googleUser = await googleSignIn.signIn();
GoogleSignInAuthentication googleAuth = await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
FirebaseUser firebaseUser = await firebaseAuth.signInWithCredential(credential);
if (firebaseUser != null) {
// Check is already sign up
final QuerySnapshot result =
await Firestore.instance.collection('users').where('id', isEqualTo: firebaseUser.uid).getDocuments();
final List<DocumentSnapshot> documents = result.documents;
if (documents.length == 0) {
// Update data to server if new user
Firestore.instance
.collection('users')
.document(firebaseUser.uid)
.setData({'nickname': firebaseUser.displayName, 'photoUrl': firebaseUser.photoUrl, 'id': firebaseUser.uid});
// Write data to local
currentUser = firebaseUser;
await prefs.setString('id', currentUser.uid);
await prefs.setString('nickname', currentUser.displayName);
await prefs.setString('photoUrl', currentUser.photoUrl);
} else {
// Write data to local
await prefs.setString('id', documents[0]['id']);
await prefs.setString('nickname', documents[0]['nickname']);
await prefs.setString('photoUrl', documents[0]['photoUrl']);
await prefs.setString('aboutMe', documents[0]['aboutMe']);
}
Fluttertoast.showToast(msg: "Sign in success");
this.setState(() {
isLoading = false;
});
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MainScreen(
currentUserId: firebaseUser.uid,
)),
);
} else {
Fluttertoast.showToast(msg: "Sign in fail");
this.setState(() {
isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
widget.title,
style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
),
centerTitle: true,
),
body: Stack(
children: <Widget>[
Center(
child: FlatButton(
onPressed: handleSignIn,
child: Text(
'SIGN IN WITH GOOGLE',
style: TextStyle(fontSize: 16.0),
),
color: Color(0xffdd4b39),
highlightColor: Color(0xffff7f7f),
splashColor: Colors.transparent,
textColor: Colors.white,
padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0)),
),
// Loading
Positioned(
child: isLoading
? Container(
child: Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(themeColor),
),
),
color: Colors.white.withOpacity(0.8),
)
: Container(),
),
],
));
}
}
2) main.dart
import 'dart:async';
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:p_chat_2/chat.dart';
import 'package:p_chat_2/const.dart';
import 'package:p_chat_2/login.dart';
import 'package:p_chat_2/settings.dart';
void main() => runApp(MyApp());
class MainScreen extends StatefulWidget {
final String currentUserId;
MainScreen({Key key, @required this.currentUserId}) : super(key: key);
@override
State createState() => MainScreenState(currentUserId: currentUserId);
}
class MainScreenState extends State<MainScreen> {
MainScreenState({Key key, @required this.currentUserId});
final String currentUserId;
bool isLoading = false;
List<Choice> choices = const <Choice>[
const Choice(title: 'Settings', icon: Icons.settings),
const Choice(title: 'Log out', icon: Icons.exit_to_app),
];
Future<bool> onBackPress() {
openDialog();
return Future.value(false);
}
Future<Null> openDialog() async {
switch (await showDialog(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
contentPadding: EdgeInsets.only(left: 0.0, right: 0.0, top: 0.0, bottom: 0.0),
children: <Widget>[
Container(
color: themeColor,
margin: EdgeInsets.all(0.0),
padding: EdgeInsets.only(bottom: 10.0, top: 10.0),
height: 100.0,
child: Column(
children: <Widget>[
Container(
child: Icon(
Icons.exit_to_app,
size: 30.0,
color: Colors.white,
),
margin: EdgeInsets.only(bottom: 10.0),
),
Text(
'Exit app',
style: TextStyle(color: Colors.white, fontSize: 18.0, fontWeight: FontWeight.bold),
),
Text(
'Are you sure to exit app?',
style: TextStyle(color: Colors.white70, fontSize: 14.0),
),
],
),
),
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, 0);
},
child: Row(
children: <Widget>[
Container(
child: Icon(
Icons.cancel,
color: primaryColor,
),
margin: EdgeInsets.only(right: 10.0),
),
Text(
'CANCEL',
style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
)
],
),
),
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, 1);
},
child: Row(
children: <Widget>[
Container(
child: Icon(
Icons.check_circle,
color: primaryColor,
),
margin: EdgeInsets.only(right: 10.0),
),
Text(
'YES',
style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
)
],
),
),
],
);
})) {
case 0:
break;
case 1:
exit(0);
break;
}
}
Widget buildItem(BuildContext context, DocumentSnapshot document) {
if (document['id'] == currentUserId) {
return Container();
} else {
return Container(
child: FlatButton(
child: Row(
children: <Widget>[
Material(
child: document['photoUrl'] != null
? CachedNetworkImage(
placeholder: (context, url) => Container(
child: CircularProgressIndicator(
strokeWidth: 1.0,
valueColor: AlwaysStoppedAnimation<Color>(themeColor),
),
width: 50.0,
height: 50.0,
padding: EdgeInsets.all(15.0),
),
imageUrl: document['photoUrl'],
width: 50.0,
height: 50.0,
fit: BoxFit.cover,
)
: Icon(
Icons.account_circle,
size: 50.0,
color: greyColor,
),
borderRadius: BorderRadius.all(Radius.circular(25.0)),
clipBehavior: Clip.hardEdge,
),
Flexible(
child: Container(
child: Column(
children: <Widget>[
Container(
child: Text(
'Nickname: ${document['nickname']}',
style: TextStyle(color: primaryColor),
),
alignment: Alignment.centerLeft,
margin: EdgeInsets.fromLTRB(10.0, 0.0, 0.0, 5.0),
),
Container(
child: Text(
'About me: ${document['aboutMe'] ?? 'Not available'}',
style: TextStyle(color: primaryColor),
),
alignment: Alignment.centerLeft,
margin: EdgeInsets.fromLTRB(10.0, 0.0, 0.0, 0.0),
)
],
),
margin: EdgeInsets.only(left: 20.0),
),
),
],
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Chat(
peerId: document.documentID,
peerAvatar: document['photoUrl'],
)));
},
color: greyColor2,
padding: EdgeInsets.fromLTRB(25.0, 10.0, 25.0, 10.0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
),
margin: EdgeInsets.only(bottom: 10.0, left: 5.0, right: 5.0),
);
}
}
final GoogleSignIn googleSignIn = GoogleSignIn();
void onItemMenuPress(Choice choice) {
if (choice.title == 'Log out') {
handleSignOut();
} else {
Navigator.push(context, MaterialPageRoute(builder: (context) => Settings()));
}
}
Future<Null> handleSignOut() async {
this.setState(() {
isLoading = true;
});
await FirebaseAuth.instance.signOut();
await googleSignIn.disconnect();
await googleSignIn.signOut();
this.setState(() {
isLoading = false;
});
Navigator.of(context)
.pushAndRemoveUntil(MaterialPageRoute(builder: (context) => MyApp()), (Route<dynamic> route) => false);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'MAIN',
style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
),
centerTitle: true,
actions: <Widget>[
PopupMenuButton<Choice>(
onSelected: onItemMenuPress,
itemBuilder: (BuildContext context) {
return choices.map((Choice choice) {
return PopupMenuItem<Choice>(
value: choice,
child: Row(
children: <Widget>[
Icon(
choice.icon,
color: primaryColor,
),
Container(
width: 10.0,
),
Text(
choice.title,
style: TextStyle(color: primaryColor),
),
],
));
}).toList();
},
),
],
),
body: WillPopScope(
child: Stack(
children: <Widget>[
// List
Container(
child: StreamBuilder(
stream: Firestore.instance.collection('users').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(themeColor),
),
);
} else {
return ListView.builder(
padding: EdgeInsets.all(10.0),
itemBuilder: (context, index) => buildItem(context, snapshot.data.documents[index]),
itemCount: snapshot.data.documents.length,
);
}
},
),
),
// Loading
Positioned(
child: isLoading
? Container(
child: Center(
child: CircularProgressIndicator(valueColor: AlwaysStoppedAnimation<Color>(themeColor)),
),
color: Colors.white.withOpacity(0.8),
)
: Container(),
)
],
),
onWillPop: onBackPress,
),
);
}
}
class Choice {
const Choice({this.title, this.icon});
final String title;
final IconData icon;
}
Примечание: login.dart должен перейти к main.dart, но этого не происходит.Спасибо: