'Flutter Google Sign in, Endless loading Icon when selecting an existing account
I get endless loading Icon when selecting an existing account
I can create an account just fine for the first time and login, but when i close android studio then restart main.dart & emulator then try to sign in to that existing account, i get infinite loading icon :
Here's the loginPage.dart code:-
import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:telegramchatapp/Pages/HomePage.dart';
import 'package:telegramchatapp/Widgets/ProgressWidget.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LoginScreen extends StatefulWidget {
LoginScreen({Key key}) : super(key : key);
@override
LoginScreenState createState() => LoginScreenState();
}
class LoginScreenState extends State<LoginScreen> {
final GoogleSignIn googleSignIn = GoogleSignIn();
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
SharedPreferences preferences;
bool isLoggedIn = false;
bool isLoading = false;
FirebaseUser currentUser;
@override
void initState() {
// TODO: implement initState
super.initState();
isSignedIn();
}
void isSignedIn() async{
this.setState(() {
isLoggedIn = true;
});
preferences = await SharedPreferences.getInstance();
isLoggedIn = await googleSignIn.isSignedIn();
if(isLoggedIn){
Navigator.push(context, MaterialPageRoute(builder: (context) => HomeScreen(currentUserId: preferences.getString("id"))));
}
this.setState(() {
isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [Colors.blueAccent, Colors.black12],
),
),
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
"Solef App",
style: TextStyle(fontSize: 82.0, color: Colors.white, fontFamily: "Signatra"),
),
GestureDetector(
onTap: controlSignIn,
child: Center(
child: Column(
children: <Widget>[
Container(
width: 270.0,
height: 65.0,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
"assets/images/google_signin_button.png"),
),
),
),
Padding(
padding: EdgeInsets.all(1.0),
child: isLoading ? circularProgress() : Container(),
),
],
),
),
)
],
),
),
);
}
Future<Null> controlSignIn() async {
preferences = await SharedPreferences.getInstance();
this.setState(() {
isLoading = true;
});
/*GoogleSignIn _googleSignIn = GoogleSignIn(
scopes: [
'email',
'https://www.googleapis.com/auth/contacts.readonly',
],
);*/
GoogleSignInAccount googleUser = await googleSignIn.signIn();
GoogleSignInAuthentication googleAuthentication = await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(idToken: googleAuthentication.idToken, accessToken: googleAuthentication.accessToken);
FirebaseUser firebaseUser = (await firebaseAuth.signInWithCredential(credential)).user;
//SignIn Success
if(firebaseUser != null){
//check if already signup
final QuerySnapshot resultQuery = await Firestore.instance.collection("users").where("id", isEqualTo: firebaseUser.uid).getDocuments();
final List<DocumentSnapshot> documentSnapshots = resultQuery.documents;
//save data to firestore - if new user
if(documentSnapshots.length == 0){
Firestore.instance.collection("users").document(firebaseUser.uid).setData(
{
"nickname": firebaseUser.displayName,
"photoUrl": firebaseUser.photoUrl,
"id": firebaseUser.uid,
"aboutMe": "I'm using SOLEF chat app.",
"createdAt": DateTime.now().millisecondsSinceEpoch.toString(),
"chatingWith": null,
});
//write data to Local
currentUser = firebaseUser;
await preferences.setString("id", currentUser.uid);
await preferences.setString("nickname", currentUser.displayName);
await preferences.setString("photoUrl", currentUser.photoUrl);
}else{
//write data to Local
currentUser = firebaseUser;
await preferences.setString("id", documentSnapshots[0]["id"]);
await preferences.setString("nickname", documentSnapshots[0]["nickname"]);
await preferences.setString("photoUrl", documentSnapshots[0]["photoUrl"]);
await preferences.setString("aboutMe", documentSnapshots[0]["aboutMe"]);
}
Fluttertoast.showToast(msg: "SignIn Successful.");
this.setState(() {
isLoading = false;
});
Navigator.push(context, MaterialPageRoute(builder: (context) => HomeScreen(currentUserId: firebaseUser.uid)));
}
//SignIn Not Success - Failed
else{
Fluttertoast.showToast(msg: "Try Again, SignIn Failed.");
this.setState(() {
isLoading = false;
});
}
}
}
Here's the Homepage.dart:
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import '../main.dart';
class HomeScreen extends StatefulWidget {
final String currentUserId;
HomeScreen({Key key, @required this.currentUserId}) : super(key : key);
@override
State createState() => HomeScreenState();
}
class HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
return RaisedButton.icon(onPressed: logoutUser, icon: Icon(Icons.close), label: Text("Sign Out"));
}
final GoogleSignIn googleSignIn = GoogleSignIn();
Future<Null> logoutUser() async{
await FirebaseAuth.instance.signOut();
await googleSignIn.disconnect();
await googleSignIn.signOut();
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => MyApp()), (Route<dynamic> route ) => false);
}
}
class UserResult extends StatelessWidget
{
@override
Widget build(BuildContext context) {
}
}
Solution 1:[1]
The problem is you're not using the try catch block. For example, you can do something like this:
Future signInAnon() async {
setState(() {
_isLoading = true;
});
FirebaseAuth auth = FirebaseAuth.instance;
try {
await auth.signInAnonymously();
} on FirebaseAuthException catch (e) {
setState(() {
_isLoading = false;
});
showSimpleNotification(
const Text(
'Sign In Error',
style: TextStyle(color: Colors.white),
textAlign: TextAlign.center,
),
contentPadding: const EdgeInsets.all(12),
background: Colors.red,
);
} catch (e) {
setState(() {
_isLoading = false;
});
}
}
Then, on listening to the user signing, you can do this:
class AppWrapper extends StatefulWidget {
const AppWrapper({Key? key}) : super(key: key);
@override
_AppWrapperState createState() => _AppWrapperState();
}
class _AppWrapperState extends State<AppWrapper> {
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, AsyncSnapshot<User?> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return errorPage();
} else if (snapshot.hasData) {
return const HomePage();
} else {
return const SigningPage();
}
},
);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | dev.bojack |

