How to SignIn with google on Parse Server - flutter

I'm developing an application with Flutter and Parse Server and I want to register Users from google account.
I have tried:
static Future<void> loginWithGoogle() async {
try {
final _googleSignIn = GoogleSignIn(scopes: ['email', 'https://www.googleapis.com/auth/contacts.readonly']);
final account = await _googleSignIn.signIn(); // I figure out that the real error is here;
final authentication = await account.authentication;
final googleAuth = google(_googleSignIn.currentUser.id, authentication.accessToken, authentication.idToken);
final response = await ParseUser.loginWith('google', googleAuth);
if (response.success) {
print(response);
//currentUser = await ParseUser.currentUser(customUserObject: User.clone());
//Get.offNamed('/oauth');
}
} catch (e) {
print(e);
AlertUtils.showErrorDialog(e.toString());
}
}
but here I faced that error:
plugin: PlatformException(sign_in_failed,
com.google.android.gms.common.api.ApiException: 10: , null)

You cannot do this without registering on Firebase. The official documentation says so.

Related

Sending emails using app with flutter using SMPT

I have tried to send emails using app, that app is built using flutter framework. There is no error while it is running but emails are not sent. This is my code.
**send email function**
Future sendEmail(subject,msg) async{
final user = await GoogleAuthApi.signIn();
if(user == null) return;
final email = user.email;
final auth = await user.authentication;
final token =auth.accessToken!;
final smtpServer = gmailRelaySaslXoauth2(email, token);
final message = Message()
..from = Address(email,'test')
..recipients = ["test#gmail.com"]
..subject = subject.toString()
..text=msg.toString();
try{
await send(message,smtpServer);
showSnackBar('Sent email successfully!');
}on MailerException catch(e){
print("hi==$e");
}
}
class GoogleAuthApi{
static final _googleSignIn = GoogleSignIn(scopes: ['https://mail.google.com/']);
static Future<GoogleSignInAccount?> signIn() async{
if(await _googleSignIn.isSignedIn()){
return _googleSignIn.currentUser;
}else {
return await _googleSignIn.signIn();
}
}
}

Error getting thrown when trying to sign in with Google Auth to Firestore

I am trying to create a google sign in option for my app. I appear to be getting back a valid Token Id from google but my app is crashing in the ios Emulator and the following error is being shown in console.
flutter: [firebase_auth/invalid-credential] Unable to parse Google id_token: ya29.A0ARrdaM_uqbYHorJh1kJXTXac7MEm2TjD.......
When I cancel the login an error is successfully being thrown from my code. Can anyone help me out?
flutter: [firebase_auth/sign_in_canceled] The user canceled the sign-in flow.
#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.accessToken,
));
return UserCredential.user;
} else {
throw FirebaseAuthException(
code: 'ERROR_MISSING_GOOGLE_ID_TOKEN',
message: 'Missing Google ID Token',
);
}
} else {
throw FirebaseAuthException(
code: 'sign_in_canceled',
message: 'The user canceled the sign-in flow.',
);
}
}
I figured it out. This line needed to be changed to pass the idToken...not the accessToken.
idToken: googleAuth.idToken,

Flutter - Google Sign In uses previously signed in account (user) even after signing out and signing in with another account

When I hit "Sign in with Google", it does let me choose the account although somehow, the previous user gets loaded.
class GoogleSignInProvider extends ChangeNotifier {
GoogleSignIn? _googleSignIn;
GoogleSignInAccount? _user;
GoogleSignInAccount get user => _user!;
bool _isGoogleLogin = false;
final _auth = FirebaseAuth.instance;
Future signInWithGoogle(context) async {
try {
_googleSignIn = GoogleSignIn();
final googleUser = await _googleSignIn!.signIn();
if (googleUser == null) {
return;
}
_user = googleUser;
final googleAuth = await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
var authCredential = await _auth.signInWithCredential(credential);
_isGoogleLogin = true;
if (authCredential.user != null) {
final snapshot = await FirebaseFirestore.instance
.collection('users')
.doc(authCredential.user!.uid)
.get();
if (!snapshot.exists) {
var userId = authCredential.user!.uid;
FirebaseFirestore.instance.collection('users').doc(userId).set({
"email": googleUser.email,
"workoutsCount": 0,
"lastWorkoutDate": null
});
}
}
notifyListeners();
Navigator.of(context).pushNamed('/dashboard');
} on FirebaseAuthException catch (e) {
showSnackBar(context, e);
} catch (e) {
print('ERROR = ');
print(e);
}
}
Future<void> signOut(context) async {
try {
if (_isGoogleLogin) {
final googleCurrentUser =
GoogleSignIn().currentUser ?? await GoogleSignIn().signIn();
if (googleCurrentUser != null) {
await GoogleSignIn().disconnect().catchError((e, stack) {
FirebaseCrashlytics.instance.recordError(e, stack);
});
}
}
await _auth.signOut();
} catch (e) {
showSnackBar(context, e);
} finally {
_isGoogleLogin = false;
Navigator.of(context).pushNamedAndRemoveUntil(
'/register_login', (Route<dynamic> route) => false);
}
}
Is there something wrong with this code??
Can you try to disconnect the account before signing out:
GoogleSignIn _googleSignIn = GoogleSignIn();
await _googleSignIn.disconnect();
await FirebaseAuth.instance.signOut();
You are using firebase auth then please use thsi for signout user :
How to Signout a user in Flutter with Firebase authentication
Remove if (_isGoogleLogin) from your signOut function. googleCurrentUser will check the consitionn and responses based on the result.
First Create a Global variable
FirebaseAuth firebaseAuth = FirebaseAuth.instance;
GoogleSignIn googleSignIn = GoogleSignIn();
Make sure you are using the above variable for login and logout
final googleCurrentUser = firebaseAuth.currentUser;
if (googleCurrentUser != null) {
googleSignIn.signOut();
await firebaseAuth.signOut();
}
User above code for signout user

Can't sign in using google in Flutter

I am able to Google Sign in using web version of my flutter app but can't Google sign in from android app.
This is the error I'm getting:
GraphicExtModuleLoader::CreateGraphicExtInstance false
D/Surface (29460): Surface::connect(this=0x753ab3e000,api=1)
D/Surface (29460): Surface::setBufferCount(this=0x753ab3e000,bufferCount=3)
D/Surface (29460): Surface::allocateBuffers(this=0x753ab3e000)
V/PhoneWindow(29460): DecorView setVisiblity: visibility = 0, Parent = android.view.ViewRootImpl#9837577, this = DecorView#bcd75e4[MainActivity]
V/PhoneWindow(29460): DecorView setVisiblity: visibility = 4, Parent = android.view.ViewRootImpl#9de9d56, this = DecorView#63bb4f5[SignInHubActivity]
D/Surface (29460): Surface::disconnect(this=0x753ab3e000,api=1)
D/View (29460): [Warning] assignParent to null: this = DecorView#63bb4f5[SignInHubActivity]
E/flutter (29460): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: PlatformException(sign_in_failed, com.google.android.gms.common.api.ApiException: 10: , null, null)
Refereing to this Flutter and google_sign_in plugin: PlatformException(sign_in_failed, com.google.android.gms.common.api.ApiException: 10: , null) answer on StackOverflow, I couldn't understand what this answer is trying to say...
However, I do have provided my SHA1 key on firebase. Re-downloaded and replaced the google-services.json in my flutter app, but still can't sign in on Android.
This is my GoogleSignIn code:
onPressed: () async {
await Firebase.initializeApp();
final FirebaseAuth _firebaseAuth =
FirebaseAuth.instance;
final GoogleSignIn _googleSignIn =
GoogleSignIn();
Future<User> _signIn(BuildContext context) async {
debugPrint("1");
final GoogleSignInAccount googleUser =
await _googleSignIn.signIn();
debugPrint("2");
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;
debugPrint("a");
final AuthCredential credential =
GoogleAuthProvider.credential(
idToken: googleAuth.idToken,
accessToken: googleAuth.accessToken);
User userDetails = (await _firebaseAuth
.signInWithCredential(credential))
.user;
ProviderDetails providerInfo =
ProviderDetails(userDetails.uid);
List<ProviderDetails> providerData =
<ProviderDetails>[];
providerData.add(providerInfo);
UserDetails details = UserDetails(
userDetails.uid,
userDetails.displayName,
userDetails.email,
userDetails.photoURL,
providerData);
if (details.userName.toString() != '') {
debugPrint("Email ${details.userEmail}");
globals.isLoggedIn = true;
SharedPref prefs = SharedPref();
String photoUrl = details.photoUrl.toString();
prefs.save("photoUrl", photoUrl);
prefs.save("username",
details.userName.toString());
prefs.save(
"email", details.userEmail.toString());
if (mounted) {
setState(() {
inProgress = false;
});
}
} else {
globals.isLoggedIn = false;
debugPrint(
"Check your internet Connection");
}
}
if (mounted) {
setState(() {
inProgress = true;
});
}
await _signIn(context);
debugPrint("LoggedIn");
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Dashboard()),
);
}
Actually I needed to add this line into my app level build.gradle file dependencies section.
implementation 'com.google.android.gms:play-services-auth:19.0.0'
As well needed to link my project from this link too.
https://developers.google.com/identity/sign-in/android/start-integrating#configure_a_project
Might it help someone in future!
Problem is When you registered your app on google console and created clientId, you choose web platform, now you have to create another clientId with Android Platform. You can use same sha1 key.

Google Authentication and Facebook Authentication Existing User

Hello Everyone someone please offer me some help if you can. I'm not sure if this is an issue on Firebase's side or if I failed on my code or configuring the Firebase authentication correctly.
So here's the issue.
I wanted to see if a user existed inside the firestore. If it does then link the accounts. I read the documentation and understand that when using the SigninwithCredential() it should throw an error saying something on the lines of "ERROR USER ALREADY EXISTS IN FIRESTORE".
So testing went something like this to see if I'd get an error before trying to handle the error.
Continue with Facebook (OK).
Signed In (OK).
Continue with Google (Expected Error) (Didn't throw Error)
So what happened here instead was the user originally created by Facebook was overridden by Google.
Sign In with Facebook (Expected Error) (OK) Recieved error as expected "An Account already exists but with different sign-in credentials"
Read documentation several times and compared google code with Facebook code and can't seem to find answer.
class MyFirebase {
static bool isSignIn = false;
static auth.FirebaseAuth _auth = auth.FirebaseAuth.instance;
static FacebookLogin facebookLogin = FacebookLogin();
static GoogleSignIn googleSignIn = GoogleSignIn();
static Future<auth.User> loginGoogle() async {
final prefs = await SharedPreferences.getInstance();
final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
if (googleSignInAccount == null) {
print("ERROR HAS OCCURED WITH THE GOOGLE LOGIN");
throw new Exception("ERROR HAS OCCURED WITH THE LOGIN");
} else {
final GoogleSignInAuthentication googleSignInAuthentication =
await googleSignInAccount.authentication;
var item = googleSignInAccount.photoUrl;
print("PHOTO URL" + item);
prefs.setString("photoURL", item);
final auth.AuthCredential credential = auth.GoogleAuthProvider.credential(
accessToken: googleSignInAuthentication.accessToken);
try {
var authResult = await _auth.signInWithCredential(credential);
return authResult.user;
} catch (e) {
print(e);
throw (e);
}
}
}
static Future<auth.User> loginFacebook() async {
final FacebookLoginResult result = await facebookLogin.logIn(['email']);
final prefs = await SharedPreferences.getInstance();
var a;
switch (result.status) {
case FacebookLoginStatus.cancelledByUser:
print("CANCELLED BY USER DO NOT RETURN");
throw new Exception("CANCELLED BY USER DO NOT RETURN");
break;
case FacebookLoginStatus.error:
print("ERROR OCCURED");
throw new Exception("ERROR oCCURED");
break;
case FacebookLoginStatus.loggedIn:
try {
final FacebookAccessToken accessToken = result.accessToken;
auth.AuthCredential credential =
auth.FacebookAuthProvider.credential(accessToken.token);
print("########## MAKING GRAPH RESPONSE");
final response = await http.get(
'https://graph.facebook.com/v2.12/me?fields=name,first_name,picture.width(800).height(800),last_name,email&access_token=${accessToken.token}');
final profile = jsonDecode(response.body);
String item = profile['picture']['data']['url'];
prefs.setString("photoURL", item);
a = await _auth.signInWithCredential(credential);
return a.user;
} catch (e) {
print(e);
throw e;
}
break;
}
return null;
}
static Future<void> signOut() async {
await facebookLogin.logOut();
await _auth.signOut();
await googleSignIn.signOut();
}
}
**strong text** ```