I am learning flutter and I am stuck on a problem .
I created a little app which allows me to auth via Gmail on firebase.
As soon as I get logged in the email and a generated name will be added to "collection: users"
now I would like to add some more information about the user to the "collection: profilepage".
on my main.dart I ask: is user logged in, then
return(UserNameChooser).
In UserNameChooser I have 2 textfields which will be written into "collection: profilepage".
Now my Question: How can I get the UserID from the "collection: users" and add
the ID to the "collection: profilepage".
Or how do you manage profilepage auth connection?
I tried so many ways but couldn't get it done...
My Main.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:signal/services/auth.dart';
// import 'package:signal/views/home.dart';
import 'package:signal/views/usernamechooser.dart';
import 'views/signin.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.lightBlue,
),
home: FutureBuilder(
future: AuthMethods().getCurrentUser(),
builder: (context, AsyncSnapshot<dynamic> snapshot) {
if(snapshot.hasData){
return UserNameChooser();
}
else{
return SignIn();
}
}
),
);
}
}
My auth.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:signal/helperfunctions/sharedpref_helper.dart';
import 'package:signal/services/database.dart';
import 'package:signal/views/home.dart';
class AuthMethods{
final FirebaseAuth auth = FirebaseAuth.instance;
getCurrentUser() async {
return await auth.currentUser;
}
signInWithGoogle(BuildContext context) async {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
final GoogleSignIn _googleSignIn = GoogleSignIn();
final GoogleSignInAccount googleSignInAccount =
await _googleSignIn.signIn();
final GoogleSignInAuthentication googleSignInAuthentication = await
googleSignInAccount.authentication;
final AuthCredential credential = GoogleAuthProvider.credential(
idToken: googleSignInAuthentication.idToken,
accessToken: googleSignInAuthentication.accessToken
);
UserCredential result =
await _firebaseAuth.signInWithCredential(credential);
User userDetails = result.user;
if(result != null){
SharedPreferenceHelper().saveUserEmail(userDetails.email);
SharedPreferenceHelper().saveUserId(userDetails.uid);
SharedPreferenceHelper()
.saveUserName(userDetails.email.replaceAll("#gmail.com", ""));
SharedPreferenceHelper().saveDisplayName(userDetails.displayName);
SharedPreferenceHelper().saveUserProfileUrl(userDetails.photoURL);
Map<String, dynamic> userInfoMap = {
"email": userDetails.email,
"username": userDetails.email.replaceAll("#gmail.com", ""),
"name": userDetails.displayName,
"imgUrl": userDetails.photoURL
};
DatabaseMethods()
.addUserInfoToDB(userDetails.uid, userInfoMap)
.then((value) {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => Home()));
});
}
}
Future signOut() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.clear();
await auth.signOut();
}
}
My Database.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:signal/helperfunctions/sharedpref_helper.dart';
class DatabaseMethods{
Future addUserInfoToDB(String userId, Map<String, dynamic>userInfoMap)
async {
return FirebaseFirestore.instance
.collection("users")
.doc(userId)
.set(userInfoMap);
}
Future<Stream<QuerySnapshot>> getUserByUserName(String username) async{
return FirebaseFirestore.instance
.collection("users")
.where("username", isEqualTo: username)
.snapshots();
}
Future addMessage(String chatRoomId, String messageId, Map messageInfoMap) async {
return FirebaseFirestore.instance
.collection ("chatrooms")
.doc(chatRoomId)
.collection("chats")
.doc(messageId)
.set(messageInfoMap);
}
updateLastMessageSend(String chatRoomId, Map lastMessageInfoMap){
return FirebaseFirestore.instance
.collection("chatrooms")
.doc(chatRoomId)
.update(lastMessageInfoMap);
}
createChatRoom(String chatRoomId, Map chatRoomInfoMap) async{
final snapShot = await FirebaseFirestore.instance
.collection("chatrooms")
.doc(chatRoomId)
.get();
if(snapShot.exists){
//chatroom already exists
return true;
}else{
//chatroom does not exists
return FirebaseFirestore.instance
.collection("chatrooms")
.doc(chatRoomId)
.set(chatRoomInfoMap);
}
}
Future<Stream<QuerySnapshot>> getChatRoomMessages(chatRoomId) async {
return FirebaseFirestore.instance
.collection("chatrooms")
.doc(chatRoomId)
.collection("chats")
.orderBy("ts", descending: true)
.snapshots();
}
Future<Stream<QuerySnapshot>> getChatRooms() async {
String myUsername = await SharedPreferenceHelper().getUserName();
return FirebaseFirestore.instance
.collection("chatrooms")
.orderBy("lastMessageSendTs", descending: true)
.where("users",arrayContains: myUsername)
.snapshots();
}
Future<QuerySnapshot> getUserInfo(String username) async {
return await FirebaseFirestore.instance
.collection("users")
.where("username", isEqualTo: username)
.get();
}
}
my usernamechooser.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:signal/views/home.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:signal/helperfunctions/sharedpref_helper.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(
MaterialApp(home: UserNameChooser(),));
}
class UserNameChooser extends StatefulWidget{
#override
_UserNameChooserState createState() => _UserNameChooserState();
}
class _UserNameChooserState extends State<UserNameChooser> {
String userNameKey, getUserId;
TextEditingController chosenusername = new TextEditingController();
TextEditingController chosenage = new TextEditingController();
Future<String> getUserName() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString(userNameKey);
}
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(title: Text("usernamechooser"),
),
body: Container(
padding: EdgeInsets.all(40.0),
child: Center(child: Column(
children: [
Container(
),
TextFormField(
controller: chosenusername,
decoration: InputDecoration(
hintText: "Username"
),
),
SizedBox(
height: 10.0,
),
TextFormField(
controller: chosenage,
decoration: InputDecoration(
hintText: "alter"
),
),
SizedBox(
height: 10.0,
),
TextButton(
onPressed: (){
Map <String,dynamic> data = {"choseusername": chosenusername.text,"chosenage": chosenage.text};
FirebaseFirestore.instance.collection("userprofile").add(data);
Navigator.push(context, MaterialPageRoute(builder: (context) => Home(),));
},
child: Text("Submit"),
),
]
),
)
)
);
}
}
and last but not least my shared_preferences.dart
import 'package:shared_preferences/shared_preferences.dart';
class SharedPreferenceHelper {
static String userIdKey = "USERKEY";
static String userNameKey = "USERNAMEKEY";
static String displayNameKey = "USERDISPLAYNAMEKEY";
static String userEmailKey = "USEREMAILKEY";
static String userProfilePicKey = "USERPROFILEPICKEY";
//save data
Future<bool> saveUserName(String getUserName) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.setString(userNameKey, getUserName);
}
Future<bool> saveUserEmail(String getUseremail) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.setString(userEmailKey, getUseremail);
}
Future<bool> saveUserId(String getUserId) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.setString(userIdKey, getUserId);
}
Future<bool> saveDisplayName(String getDisplayName) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.setString(displayNameKey, getDisplayName);
}
Future<bool> saveUserProfileUrl(String getUserProfile) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.setString(userProfilePicKey, getUserProfile);
}
// get data
Future<String> getUserName() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString(userNameKey);
}
Future<String> getUserEmail() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString(userEmailKey);
}
Future<String> getUserId() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString(userIdKey);
}
Future<String> getDisplayName() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString(displayNameKey);
}
Future<String> getUserProfileUrl() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString(userProfilePicKey);
}
}
Problem Solved ...
here how i did it :
I loaded the currentUser.uid into the var useruid ..
var useruid = FirebaseAuth.instance.currentUser.uid;
and sent this uid to the user db :)
Related
I am flutter-newbie and I have one problem: I want to add Google authentication to my flutter app with firebase. This is my code for login screen:
import 'package:PixiCall/resources/firebase_repository.dart';
import 'package:PixiCall/screens/home_screen.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class LoginScreen extends StatefulWidget {
#override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
FirebaseRepository _repository = FirebaseRepository();
#override
Widget build(BuildContext context) {
return Scaffold(
body: loginButton(),
);
}
Widget loginButton() {
return FlatButton(
padding: EdgeInsets.all(35),
child: Text(
'Login',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.w900,
letterSpacing: 1.2,
),
),
onPressed: () => performLogin,
);
}
void performLogin() {
_repository.signIn().then((User user) {
if (user != null) {
authenticateUser(user);
} else {
print('There was an error');
}
});
}
void authenticateUser(User user, BuildContext context) {
_repository.authenticateUser(user).then((isNewUser) {
if (isNewUser) {
_repository.addDataToDb(user).then((value) {
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) {
return HomeScreen();
}));
});
} else {
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) {
return HomeScreen();
}));
}
});
}
}
I have this error here:
lib/screens/login_screen.dart:39:25: Error: Too few positional arguments: 2 required, 1 given.
authenticateUser(user);
What is the other parameter which I have to add?
Also I think that I have one more mistake in other file. This is the code from other file:
import 'package:PixiCall/models/user.dart';
import 'package:PixiCall/utils/utilities.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
class FirebaseMethods {
final FirebaseAuth _auth = FirebaseAuth.instance;
GoogleSignIn _googleSignIn = GoogleSignIn();
static final FirebaseFirestore firestore = FirebaseFirestore.instance;
//user class
User1 user = User1();
Future<User> getCurrentUser() async {
User currentUser;
currentUser = await _auth.currentUser;
return currentUser;
}
Future<User> signIn() async {
GoogleSignInAccount _signInAccount = await _googleSignIn.signIn();
GoogleSignInAuthentication _signInAuthentication =
await _signInAccount.authentication;
final AuthCredential credential = GoogleAuthProvider.credential(
accessToken: _signInAuthentication.accessToken,
idToken: _signInAuthentication.idToken,
);
User user = await _auth.signInWithCredential(credential);
return user;
}
Future<bool> authenicateUser(User user) async {
QuerySnapshot result = await firestore
.collection('users')
.where('email', isEqualTo: user.email)
.get();
final List<DocumentSnapshot> docs = result.docs;
//if user is registered then length of list > 0 or else less than 0
return docs.length == 0 ? true : false;
}
Future<void> addDataToDb(User currentUser) async {
String username = Utils.getUsername(currentUser.email);
user = User1(
uid: currentUser.uid,
email: currentUser.email,
name: currentUser.displayName,
profilePhoto: currentUser.photoURL,
username: username);
firestore.collection('users').doc(currentUser.uid).set(user.toMap(user));
}
}
This is the mistake in console:
lib/resources/firebase_methods.dart:32:17: Error: A value of type 'UserCredential' can't be assigned to a variable of type 'User'.
Sorry if I confused you, as I said, I am newbie. If you want any other informations please ask here.
For the first mistake , you defined a function void authenticateUser(User user, BuildContext context) so when you use it, it expects 2 arguments a User type object and a BuildContext object
Then you are calling this function in
void performLogin() {
_repository.signIn().then((User user) {
if (user != null) {
authenticateUser(user);
} else {
print('There was an error');
}
});
}
You are passing only the User object, missing the BuildContext
For GoogleSingIn this was my solution:
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
final GoogleSignIn _googleSignIn = GoogleSignIn();
//create user object based on FB json
User _userFromFirebaseUser(FirebaseUser user) {
return user != null
? User(uid: user.uid, emailVerified: user.isEmailVerified)
: null;
}
//auth change user stream
Stream<User> get user {
return _auth.onAuthStateChanged.map(_userFromFirebaseUser);
}
Future<User> singInUsingGoogle() async {
int age;
String email;
String name;
String lastname;
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(
idToken: googleAuth.idToken, accessToken: googleAuth.accessToken);
final result = await _auth.signInWithCredential(credential);
FirebaseUser user = result.user;
print(result.user.providerData);
await DatabaseService(uid: user.uid).createUserData(
//user info
)
Unhandled Exception: type 'Future' is not a subtype of type 'QuerySnapshot' in flutter googlesignin using firebase.Got problem with this line: final QuerySnapshot result=FirebaseFirestore.instance.collection('users').where('id',isEqualTo: user.uid).get();
it is used for sign inwith google using firebase
import 'package:shared_preferences/shared_preferences.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'home.dart';
import 'package:flutter_auth_buttons/flutter_auth_buttons.dart';
import 'package:flutter_signin_button/flutter_signin_button.dart';
class Login extends StatefulWidget {
#override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
final GoogleSignIn googleSignIn = new GoogleSignIn();
SharedPreferences preferences;
bool loading = false;
bool isLogedIn = false;
#override
void initState() {
super.initState();
isSignedIn();
}
void isSignedIn() async {
setState(() {
loading = true;
});
preferences = await SharedPreferences.getInstance();
isLogedIn = await googleSignIn.isSignedIn();
if (isLogedIn) {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => HomePage()));
}
setState(() {
loading = false;
});
}
Future<Null> handleSignIn() async{
preferences = await SharedPreferences.getInstance();
final GoogleSignInAccount googleUser = await googleSignIn.signIn();
final GoogleSignInAuthentication googleSignInAuthentication = await googleUser.authentication;
AuthCredential credential = GoogleAuthProvider.credential(idToken: googleSignInAuthentication.idToken, accessToken: googleSignInAuthentication.accessToken);
//final UserCredential userCredential = await firebaseAuth.signInWithCredential(credential);
//final User user = userCredential.user;
User user = (await firebaseAuth.signInWithCredential(credential)).user;```
if(user!=null)
{
final QuerySnapshot result=FirebaseFirestore.instance.collection('users').where('id',isEqualTo: user.uid).get();
List<DocumentSnapshot> documents= result.docs;
if(documents.length==0)
{
//insert user to collection
FirebaseFirestore.instance.collection('users').doc(user.uid).set({
"id":user.uid,
"username":user.displayName,
"photourl":user.photoURL});
await preferences.setString("id", user.uid);
await preferences.setString("username", user.displayName);
await preferences.setString("photourl", user.photoURL);
}
else{
// await preferences.setString("id",documents[0].data['id']);
//await preferences.setString("photourl",documents[0]['photourl']);
//await preferences.setString("username",documents[0]['username']);
await preferences.setString("id", documents[0].data()['id']);
await preferences.setString("username", documents[0].data()['username']);
await preferences.setString("photourl", documents[0].data()['photoUrl']);
}
Fluttertoast.showToast(msg: "Login Was successful");
setState(() {
loading=false;
});
Navigator.push(context, MaterialPageRoute(builder: (context)=>HomePage()));
}else{
Fluttertoast.showToast(msg: "Login Failed");
setState(() {
loading=false;
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children:<Widget> [
Center(
child: FlatButton(
color: Colors.red,
onPressed: (){handleSignIn();},child: Text("sigin",style: TextStyle(color: Colors.white),),
)
),
Visibility(
visible: loading ?? true,
child: Center(
child: Container(
alignment: Alignment.center,
color: Colors.white.withOpacity(0.8),
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.red),
),
)
)
)
],
),
);
}
}```
get() returns a Future<QuerySnapshot>, therefore you need to do the following:
final QuerySnapshot result= await FirebaseFirestore.instance.collection('users').where('id',isEqualTo: user.uid).get();
https://dart.dev/codelabs/async-await
When i try to sign in with my google account in the app i get this error in the console
And the app shut down , i used the sign in method in firebase- google
And this is the code that i used for the sign up page
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
class LoginScreen extends StatefulWidget {
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
LoginButton(), // <-- Built with StreamBuilder
UserProfile()
],
)));
}
}
class UserProfile extends StatefulWidget {
#override
UserProfileState createState() => UserProfileState();
}
class UserProfileState extends State<UserProfile> {
Map<String, dynamic> _profile;
bool _loading = false;
#override
initState() {
super.initState();
// Subscriptions are created here
authService.profile.listen((state) => setState(() => _profile = state));
authService.loading.listen((state) => setState(() => _loading = state));
}
#override
Widget build(BuildContext context) {
return Column(children: <Widget>[
Container(padding: EdgeInsets.all(20), child: Text(_profile.toString())),
Text(_loading.toString())
]);
}
}
class LoginButton extends StatelessWidget {
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: authService.user,
builder: (context, snapshot) {
if (snapshot.hasData) {
return MaterialButton(
onPressed: () => authService.signOut(),
color: Colors.red,
textColor: Colors.white,
child: Text('Signout'),
);
} else {
return MaterialButton(
onPressed: () => authService.testSignInWithGoogle(),
color: Colors.white,
textColor: Colors.black,
child: Text('Login with Google'),
);
}
});
}
}
and this for authentification
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:rxdart/rxdart.dart';
class AuthService {
// Dependencies
final GoogleSignIn _googleSignIn = GoogleSignIn();
final FirebaseAuth _auth = FirebaseAuth.instance;
final Firestore _db = Firestore.instance;
// Shared State for Widgets
Observable<FirebaseUser> user; // firebase user
Observable<Map<String, dynamic>> profile; // custom user data in Firestore
PublishSubject loading = PublishSubject();
// constructor
AuthService() {
user = Observable(_auth.onAuthStateChanged);
profile = user.switchMap((FirebaseUser u) {
if (u != null) {
return _db
.collection('users')
.document(u.uid)
.snapshots()
.map((snap) => snap.data);
} else {
return Observable.just({});
}
});
}
Future<String> testSignInWithGoogle() async {
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
final FirebaseUser user =
(await _auth.signInWithCredential(credential)).user;
assert(user.email != null);
assert(user.displayName != null);
assert(!user.isAnonymous);
assert(await user.getIdToken() != null);
final FirebaseUser currentUser = await _auth.currentUser();
assert(user.uid == currentUser.uid);
return 'signInWithGoogle succeeded: $user';
}
Future<String> signOut() async {
try {
await _auth.signOut();
return 'SignOut';
} catch (e) {
return e.toString();
}
}
}
// TODO refactor global to InheritedWidget
final AuthService authService = AuthService();
and this is what i have in pubspec.yml:
dependencies:
flutter:
sdk: flutter
firebase_core: ^0.4.5
firebase_analytics: ^5.0.15
cloud_firestore: ^0.13.6
firebase_auth: ^0.16.1
google_sign_in: ^4.5.1
rxdart: ^0.22.6
cupertino_icons: ^0.1.3
i am trying to implement the sign in button from firebase with google , but all the tutorials are old. I have an error at :onPressed: () => authService.googleSignIn()
Here is the code that i used for authentification:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:rxdart/rxdart.dart';
class AuthService {
// Dependencies
final GoogleSignIn _googleSignIn = GoogleSignIn();
final FirebaseAuth _auth = FirebaseAuth.instance;
final Firestore _db = Firestore.instance;
// Shared State for Widgets
Observable<FirebaseUser> user; // firebase user
Observable<Map<String, dynamic>> profile; // custom user data in Firestore
PublishSubject loading = PublishSubject();
// constructor
AuthService() {
user = Observable(_auth.onAuthStateChanged);
profile = user.switchMap((FirebaseUser u) {
if (u != null) {
return _db
.collection('users')
.document(u.uid)
.snapshots()
.map((snap) => snap.data);
} else {
return Observable.just({});
}
});
}
Future<String> _testSignInWithGoogle() async {
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
final FirebaseUser user =
(await _auth.signInWithCredential(credential)).user;
assert(user.email != null);
assert(user.displayName != null);
assert(!user.isAnonymous);
assert(await user.getIdToken() != null);
final FirebaseUser currentUser = await _auth.currentUser();
assert(user.uid == currentUser.uid);
return 'signInWithGoogle succeeded: $user';
}
Future<String> signOut() async {
try {
await _auth.signOut();
return 'SignOut';
} catch (e) {
return e.toString();
}
}
}
// TODO refactor global to InheritedWidget
final AuthService authService = AuthService();
and this is for the login page
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
class LoginScreen extends StatefulWidget {
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
LoginButton(), // <-- Built with StreamBuilder
UserProfile()
],
)));
}
}
class UserProfile extends StatefulWidget {
#override
UserProfileState createState() => UserProfileState();
}
class UserProfileState extends State<UserProfile> {
Map<String, dynamic> _profile;
bool _loading = false;
#override
initState() {
super.initState();
// Subscriptions are created here
authService.profile.listen((state) => setState(() => _profile = state));
authService.loading.listen((state) => setState(() => _loading = state));
}
#override
Widget build(BuildContext context) {
return Column(children: <Widget>[
Container(padding: EdgeInsets.all(20), child: Text(_profile.toString())),
Text(_loading.toString())
]);
}
}
class LoginButton extends StatelessWidget {
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: authService.user,
builder: (context, snapshot) {
if (snapshot.hasData) {
return MaterialButton(
onPressed: () => authService.signOut(),
color: Colors.red,
textColor: Colors.white,
child: Text('Signout'),
);
} else {
return MaterialButton(
onPressed: () => authService.googleSignIn(),
color: Colors.white,
textColor: Colors.black,
child: Text('Login with Google'),
);
}
});
}
}
I thing the AuthService.googleSignIn() in async method
so the cant assign to sync method
onPressed: () => authService.googleSignIn()
use like this
onPressed: () { authService.googleSignIn() }
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
when I select the account I want to login with, it fails. I'm confuse to whats the issue, I followed the tutorial step by step. except for this code:
final AuthCredential credential = GoogleAuthProvider.getCredential(
accessToken: googleSignInAuthentication.accessToken,
idToken: googleSignInAuthentication.idToken,
);
FirebaseUser firebaseUser = await firebaseAuth.signInWithCredential(credential);
because signInWithGoogle wasn't working.
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'home_everything.dart';
class login extends StatefulWidget {
#override
_loginState createState() => _loginState();
}
class _loginState extends State<login> {
final GoogleSignIn googleSignIn = new GoogleSignIn();
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
SharedPreferences preferences;
bool loading = false;
bool isLogedin = false;
#override
void initState(){
super.initState();
isSignedIn();
}
void isSignedIn() async{
setState(() {
loading = true;
});
preferences = await SharedPreferences.getInstance();
isLogedin = await googleSignIn.isSignedIn();
if(isLogedin){
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => SongHome()));
}
setState(() {
loading = false;
});
}
Future handleSignIn() async{
preferences = await SharedPreferences.getInstance();
setState(() {
loading = true;
});
GoogleSignInAccount googleUser = await googleSignIn.signIn();
GoogleSignInAuthentication googleSignInAuthentication = await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(
accessToken: googleSignInAuthentication.accessToken,
idToken: googleSignInAuthentication.idToken,
);
FirebaseUser firebaseUser = await firebaseAuth.signInWithCredential(credential);
if(firebaseUser != null) {
final QuerySnapshot result = await Firestore.instance.collection("users")
.where("id", isEqualTo: firebaseUser.uid)
.getDocuments();
final List<DocumentSnapshot> documents = result.documents;
if (documents.length == 0) {
// insert the user into out collection
Firestore.instance.collection("users")
.document(firebaseUser.uid)
.setData({
"id": firebaseUser.uid,
"username": firebaseUser.displayName,
"profilePicture": firebaseUser.photoUrl
});
await preferences.setString("id", firebaseUser.uid);
await preferences.setString("username", firebaseUser.displayName);
await preferences.setString("photoUrl", firebaseUser.displayName);
} else {
await preferences.setString("id", documents[0]['id']);
await preferences.setString("username", documents[0]['username']);
await preferences.setString("photoUrl", documents[0]['photoUrl']);
}
Fluttertoast.showToast(msg: "Logged In");
setState(() {
loading = false;
});
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => SongHome()));
}else{
Fluttertoast.showToast(msg: "Login failed : (");
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
centerTitle: true,
title: new Text("Login", style: TextStyle(color: Colors.redAccent),),
elevation: 0.5,
),
body: Stack(
children: <Widget>[
Center(
child: FlatButton(onPressed: (){
handleSignIn();
},
child: Text("Sign In"),),
),
Visibility(
visible: loading ?? true,
child: Container(
color: Colors.white.withOpacity(0.7),
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.red),
),
),
)
],
),
);
}
}
Here is the error log:
E/flutter (15402): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: PlatformException(sign_in_failed, com.google.android.gms.common.api.ApiException: 10: , null)
try this,
FirebaseUser firebaseUser = await firebaseAuth.signInWithCredential(credential).user;