I'm trying to sign in and out using firebase google authentication.
When I hit "Sign in with Google", I can choose the account, but the previous user gets loaded.
This is my code of the class that I'm using to log in and log out:
import 'package:flutter/material.dart';
import "package:google_sign_in/google_sign_in.dart";
import "package:firebase_auth/firebase_auth.dart";
import "package:goouser/global.dart" as global;
import 'package:cloud_firestore/cloud_firestore.dart';
class GoogleLog extends ChangeNotifier {
final googleSignIn = GoogleSignIn();
GoogleSignInAccount? _user;
GoogleSignInAccount get user => _user!;
Future googleLogin() async {
try {
final googleUser = await googleSignIn.signIn();
if (googleUser == null) return;
_user = googleUser;
final googleAuth = await googleUser.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
await FirebaseAuth.instance.signInWithCredential(credential);
} on Exception catch (e) {
print(e.toString());
}
notifyListeners();
}
Future logOut() async {
await FirebaseAuth.instance.signOut();
await googleSignIn.disconnect();
}
}
I don't know what I am doing wrong!!
Related
I want to make the user login to the app with google but the pop-up is not coming on the screen. What do I do to make the pop-up appear? When I press on the "Continue with Google" button, it does nothing.
When I debug my code, the debugger straight up goes to the last print statement -
print("GOOGLE SIGN IN: ${googleSignIn.clientId}");
here is my code-
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
part 'google_sign_in_event.dart';
part 'google_sign_in_state.dart';
class GoogleSignInBloc extends Bloc<GoogleSignInEvent, GoogleSignInState> {
GoogleSignInBloc() : super(GoogleSignInInitial()) {
on<GoogleLogInEvent>((event, emit) {
GoogleSignIn googleSignIn = GoogleSignIn();
GoogleSignInAccount? _user;
// GoogleSignInAccount get user => _user!;
//final googlelogin = MeditationGoogleSignIn().googleLogIn();
Future googleLogIn() async {
try {
final googleUser = await googleSignIn.signIn();
if (googleUser == null) {
print("NO GOOGLE USER");
return null;
}
_user = googleUser;
final googleAuth = await googleUser.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
await FirebaseAuth.instance.signInWithCredential(credential);
} catch (e) {
print("THERE IS AN ERROR IN LOGIN: ${e.toString()}");
}
}
print("GOOGLE SIGN IN: ${googleSignIn.clientId}");
});
on<GoogleLogOutEvent>((event, emit) {
Future googleLogOut() async {
final googleSignIn = GoogleSignIn();
await googleSignIn.disconnect();
FirebaseAuth.instance.signOut();
}
});
}
}
Try add scopes: GoogleSignIn(scopes: ['email', 'profile'])
i have a problem with save user data to firestore i using sign in with google auth so after i want to add user data to firestore so i can not do this can you help me thanks.
this is my auth code
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';
class GoogleSignProvider extends ChangeNotifier{
final googleSignIn = GoogleSignIn();
GoogleSignInAccount? _user;
GoogleSignInAccount? get user => _user;
final FirebaseAuth _auth = FirebaseAuth.instance;
bool result = false;
Future googleLogin()async {
try {
final googleUSer = await googleSignIn.signIn();
if (googleUSer == null ) return;
_user = googleUSer;
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
final googleAuth = await googleUSer.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
);
await FirebaseAuth.instance.signInWithCredential(credential);
UserCredential userCredential = await _auth.signInWithCredential(credential);
User? user = userCredential.user;
if (user != null){
if (userCredential.additionalUserInfo!.isNewUser) {
await _firestore.collection('users').doc(user.uid).set(
{
'username': user.displayName,
'uid': user.uid,
'profilePhoto': user.photoURL,
}
);
}}
return result;
} catch (e) {
print(e.toString());
}
notifyListeners();
}
Future logout() async {
await googleSignIn.disconnect();
FirebaseAuth.instance.signOut();
}
}
Hey were you able to save the user to firestore? I have pasted the answer that worked for me.
final userGoogle = FirebaseAuth.instance.currentUser!;
await _firestore
.collection('users')
.doc(cred.user!.uid)
.set({
uid: userGoogle.uid,
name: userGoogle.displayName!,
email: userGoogle.email!,
photoURL: userGoogle.photoURL!,
});
I'm curious if this would mean that every time I login using the google account, the photo from the Google account would overwrite the photoURL, assuming it was updated from let's say the profile page. Could help little insight into it.
import 'package:flutter/material.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 'package:rxdart/rxdart.dart';
import 'homeScreen.dart';
final FirebaseService authService = FirebaseService();
class FirebaseService {
final GoogleSignIn _googleSignIn = GoogleSignIn();
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseFirestore _db = FirebaseFirestore.instance;
`Observable`<User> user;
`Observable`<Map<String, dynamic>> profile;
PublishSubject loading = PublishSubject();
FirebaseService() {
user = `Observable`(_auth.authStateChanges());
profile = user.switchMap((User u) {
if (u != null) {
return _db
.collection('users')
.doc(u.uid)
.snapshots()
.map((snap) => snap.data());
} else {
return `Observable`.just({});
}
});
}
Future<User> googleSignIn(context) async {
loading.add(true);
GoogleSignInAccount googleUser = `await _googleSignIn.signIn()`;
GoogleSignInAuthentication googleAuth = await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.credential(
idToken: googleAuth.idToken, accessToken: googleAuth.accessToken);
final authResult = await _auth.signInWithCredential(credential);
if (authResult.user != null) {
Navigator.pushNamed(context, homeScreen.id);
}
updateUserData(`authResult.user`);
print('signed in' + `authResult.user.displayName`);
loading.add(false);
return `authResult.user`;
}
void updateUserData(User user) async {
DocumentReference ref = _db.collection('users').doc(user.uid);
return ref.set(
{
'uid': user.uid,
'email': user.email,
'photoUrl': user.photoURL,
'displayName': user.displayName,
'lastSeen': DateTime.now(),
},
);
}
void signOut() {
_auth.signOut();
}
}
I used this code before 6 months or more and now I face 9 problems inside this code!!
1- Observable not work and I replaced it with Stream and the problem didn't fix!
2- Inside Future<User> googleSignIn(context) the await _googleSignIn.signIn() show a problem!
3- Also inside Future<User> googleSignIn(context) the
updateUserData(authResult.user); print('signed in' + authResult.user.displayName); loading.add(false); return authResult.user; show a problem!
this is the problems showed the studio code
All required libraries added inside pubspec.yeml and I updated them to the newest version.
After clicking sign in, choose an account pop comes up but if the user pressed back or outside of the pop-up it throws an error.
Error -
Sign in class -
class GoogleSignInProvider extends ChangeNotifier {
final googleSignIn = GoogleSignIn();
GoogleSignInAccount? _user;
GoogleSignInAccount get user => _user!;
Future googleLogin() async {
await googleSignIn.signOut();
final googleUser = await googleSignIn.signIn();
if (googleUser == null) return;
_user = googleUser;
final googleAuth = await googleUser.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken, idToken: googleAuth.idToken);
await FirebaseAuth.instance.signInWithCredential(credential);
notifyListeners();
}
}
Sign out button -
TextButton(
onPressed: () async {
final googleCurrentUser = GoogleSignIn().currentUser;
if (googleCurrentUser != null) {
await GoogleSignIn().disconnect();
}
FirebaseAuth.instance.signOut();
Navigator.pop(context);
},
child: const Text(
'Yes',
style: TextStyle(color: primaryColor),
))
Instead of if (googleUser == null) return; try using if (googleUser == null) return null;.
Here is my sign in method;
Future<UserCredential?> signInWithGoogle() async {
final _googleSignIn = GoogleSignIn();
await _googleSignIn.disconnect().catchError((e, stack) {
print(e);
});
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
// handling the exception when cancel sign in
if (googleUser == null) return null;
// Obtain the auth details from the request
final GoogleSignInAuthentication? googleAuth =
await googleUser.authentication;
// Create a new credential
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth?.accessToken,
idToken: googleAuth?.idToken,
);
return await FirebaseAuth.instance.signInWithCredential(credential);
}
The sign out method;
Future signOut() async {
var result = await FirebaseAuth.instance.signOut();
return result;
}
This only happens in debugging, in release this won't be an issue.
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
dependencies {
// Import the Firebase BoM
implementation platform('com.google.firebase:firebase-bom:29.0.1')
// Add the dependency for the Firebase SDK for Google Analytics
// When using the BoM, don't specify versions in Firebase dependencies
implementation 'com.google.firebase:firebase-analytics'
// Add the dependencies for any other desired Firebase products
// https://firebase.google.com/docs/android/setup#available-libraries
implementation 'com.facebook.android:facebook-android-sdk:latest.release'
}
}
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
abstract class AuthBase{
User get currentUser;
Stream<User> authStateChanges();
Future<User>signInAnonymously();
Future<User> signInWithGoogle();
Future<void>signOut();
}
class Auth implements AuthBase {
final _firebaseAuth = FirebaseAuth.instance;
Stream<User> authStateChanges() => _firebaseAuth.authStateChanges();
#override
User get currentUser => _firebaseAuth.currentUser;
#override
Future<User> signInAnonymously() async {
final userCredential = await _firebaseAuth.signInAnonymously();
return userCredential.user;
}
#override
Future<User> signInWithGoogle() async{
final googleSignIn = GoogleSignIn();
final googleUser = await googleSignIn.signIn();
if(googleUser !=null) {
final googleAuth = await googleUser.authentication;
if (googleAuth.idToken != null) {
final userCredential = await _firebaseAuth.signInWithCredential(
GoogleAuthProvider.credential(
idToken: googleAuth.idToken,
accessToken: googleAuth.accessToken,
));
return userCredential.user;
} else {
throw FirebaseAuthException(
code:'ERROR_MISSING_GOOGLE_ID_TOKEN',
message:'Missing Google ID Token',
);
}
}
else {
throw FirebaseAuthException(
code: 'ERROR_ABORTED_BY_USER',
message: 'Sign in aborted by user'
);
}
}
Future<User> signInWithFacebook() async{
final fb = FacebookLogin();
}
#override
Future<void> signOut() async {
final googleSignIn = GoogleSignIn();
await googleSignIn.signOut();
await _firebaseAuth.signOut();
// TODO: implement signOut
throw UnimplementedError();
}
}
`]1][1][I'm trying to implement facebook SDK into my project.I have followed all of the steps up to this point and you can find the link below but I'm still getting an error When I copied this code in to the Main activity page.What am I doing wrong?I posted my auth.dart file and the dependencies as well
package com.example.time_trackerpractice
import io.flutter.embedding.android.FlutterActivity
import com.facebook.FacebookSdk;
import com.facebook.appevents.AppEventsLogger;
class MainActivity: FlutterActivity() {
}
The problem that you have (see image) its because you don't have any flutter packages related to facebook auth.
In this line of your code you are try instance a FacebookLogin, but doesn't exits any import related to facebook login.
final fb = FacebookLogin();
You can use this package to facebook login (flutter_facebook_auth), and replace your inside code of your function signInWithFacebook for this:
Future<User> signInWithFacebook() async {
final result = await FacebookAuth.instance
.login(permissions: ['email', 'public_profile']);
final accessToken = result.accessToken;
final credential = FacebookAuthProvider.credential(accessToken.token);
userCredential = await _firebaseAuth.signInWithCredential(credential);
return userCredential.user
}