Home > Software engineering >  How to integrate Firebase's Google sign in into Flutter project with different programming envi
How to integrate Firebase's Google sign in into Flutter project with different programming envi

Time:10-09

My current project has 2 development environments, dev and production, you can use the keyword "fluter flavor" to find out how to do it. I have found a way to apply Facebook auth in the project but with Google, it is not possible.

This is the order in which the error occurs

  1. press the login button
  2. choose a google account to login
  3. pop-up select account disappear and appear PlatformException error in terminal

Firebase google login

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:flutter/foundation.dart' show kIsWeb;

Future<User?> signInWithGoogle() async {
  FirebaseAuth auth = FirebaseAuth.instance;
  User? user;

  final GoogleSignIn googleSignIn = GoogleSignIn();

  final GoogleSignInAccount? googleSignInAccount = await googleSignIn.signIn();

  if (googleSignInAccount != null) {
    final GoogleSignInAuthentication googleSignInAuthentication =
        await googleSignInAccount.authentication;

    final AuthCredential credential = GoogleAuthProvider.credential(
      accessToken: googleSignInAuthentication.accessToken,
      idToken: googleSignInAuthentication.idToken,
    );

    try {
      final UserCredential userCredential =
          await auth.signInWithCredential(credential);
      user = userCredential.user;
    } on FirebaseAuthException catch (e) {
      if (e.code == 'account-exists-with-different-credential') {
        print("account-exists-with-different-credential");
// handle the error here
      } else if (e.code == 'invalid-credential') {
        print("invalid-credential");
// handle the error here
      }
    } catch (e) {
      print("another erro ${e}");
// handle the error here
    }
  }

  return user;
}

main.dart for dev flavor

import 'dart:async';
import 'package:com.bnk.myvincom/ui/my_app.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'config/app_config.dart';
import 'constants/strings.dart';
import 'di/components/service_locator.dart';
// import 'firebase_a'
import 'package:firebase_crashlytics/firebase_crashlytics.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await setPreferredOrientations();
  await setupLocator();

  // Initialize Firebase.
  await Firebase.initializeApp();

  // dev config
  AppConfig devAppConfig = AppConfig(appName: Strings.appNameDev, flavor: 'dev');

  // This line code just to test if crash server work, it make app crash
  // FirebaseCrashlytics.instance.crash();

  return runZonedGuarded(() async {
    // WidgetsFlutterBinding.ensureInitialized();
    runApp(MyApp(devAppConfig));
  }, (error, stack) {
    print(stack);
    print(error);
  });
}

Future<void> setPreferredOrientations() {
  return SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown,
    DeviceOrientation.landscapeRight,
    DeviceOrientation.landscapeLeft,
  ]);
}

login page

import 'package:com.bnk.myvincom/services/firebase_facebook_login_service.dart';
import 'package:com.bnk.myvincom/services/firebass_google_login_service.dart';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
// import 'package:flutter_';

class FacebookLogin extends StatefulWidget {
  @override
  _FacebookLoginState createState() => _FacebookLoginState();
}

class _FacebookLoginState extends State<FacebookLogin> {
  final _auth = FirebaseAuth.instance;
  bool _isLoggedIn = false;
  String? _message;

  Future _loginWithFacebook() async {
    // TODO: handle login
    try {
      await signInWithFacebook().then((value) => {
            print("Facebook  ${value}"),
            setState(() {
              _message = "Logged in as ${value.user!.displayName}";
              _isLoggedIn = true;
            })
          });
    } on FirebaseAuthException catch (e) {
      print('Facebook failed with error code: ${e.code}');
      print(e.message);
    }
  }

  Future _loginWithGoogle() async {
    // TODO: handle login
    try {
      await signInWithGoogle().then((value) => print("Google về ${value}"));
    } on FirebaseAuthException catch (e) {
      print('Google failed with error code: ${e.code}');
      print(e.message);
    }
  }

  Future _logout() async {
    // TODO: Handle logout
    // SignOut khỏi Firebase Auth
    await _auth.signOut();
    // Logout facebook
    // await _facebooklogin.logOut();
    setState(() {
      _isLoggedIn = false;
    });
  }

  Future _checkLogin() async {
    // TODO: check if user logged in
    // Kiểm tra xem user đã đăng nhập hay chưa
    final user = await _auth.currentUser;
    if (user != null) {
      setState(() {
        _message = "Logged in as ${user.displayName}";
        _isLoggedIn = true;
      });
    }
  }

  _buildFacebookLogin() {
    return Center(
      child: _isLoggedIn
          ? Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(_message!),
                SizedBox(height: 12.0),
                OutlineButton(
                  onPressed: () {
                    _logout();
                  },
                  child: Text('Logout'),
                ),
              ],
            )
          : RaisedButton(
              onPressed: () {
                _loginWithFacebook();
              },
              color: Colors.blue,
              textColor: Colors.white,
              child: Text('Login with Facebook'),
            ),
    );
  }

  @override
  void initState() {
    super.initState();
    _checkLogin();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        _buildFacebookLogin(),
        SizedBox(height: 30),
        _buildGoogleLogin(),
      ],
    ));
  }

  _buildGoogleLogin() {
    return Center(
      child: _isLoggedIn
          ? Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(_message!),
                SizedBox(height: 12.0),
                OutlineButton(
                  onPressed: () {
                    _logout();
                  },
                  child: Text('Logout'),
                ),
              ],
            )
          : RaisedButton(
              onPressed: () {
                _loginWithGoogle();
              },
              // color: Colors.blue,
              textColor: Colors.red,
              child: Text('Login with Google'),
            ),
    );
  }
}

Error log enter image description here

CodePudding user response:

Can you please try if it helps

  • Uninstall App
  • Flutter Clean
  • Add Debug Sha1 in firebase console if it's not there
  • Download and google-service.json
  • Run app on device

CodePudding user response:

If you tried everything like creating a new debug.toolkey, adding SHA1 and SHA-256 and it still doesn't work, you're not the only one.

The reason the above ways don't work is that their project is not either a personal project or is not split into multiple development environments. As I mentioned my project has 2 environments dev and prod. This is something that makes your brain explode, by default google-service.json only corresponds to the package you registered for firebase. That is, you use the package "com.iosBK.todoapp" to register, but in the google-service.json file on your computer, it is named "com.iosBK.todoapp.dev" or "com.iosBK.todoapp.prod" (how many development environments you have, the more google-service.json files you have).

If it's too hard to understand, think of it as simple as this. On the local machine you have 2 environments, dev and prod, there will be 2 packages com.iosBK.todoapp.dev and com.iosBK.todoapp.prod corresponding to dev and prod development environments. But on the firebase side, there will only be one package, com.iosBK.todoapp, as registered before. So when you run the app, Firebase doesn't recognize your package, causing an PlatformException error.

Do this to fix this error

  1. Go to website Google Cloud console
  2. Select the project with the same name as the project you created on Firebase
  3. Look in the picture below enter image description here
  4. Click on the red shaded area as shown enter image description here

5. You will see that the default package does not have .dev or .prod

  1. Click "Create Credentials", choose "Oath client ID", choose Application type as android, and copy everything in the place you opened it just now and change only one place which is the package name (you can change the name but it doesn't matter). I will use a dummy package name to make it easier to understand, my default package is "com.ioteks.todoapp", I will copy that name and paste it in the new Oath key and add .dev like this "com.ioteks.todoapp.dev"

  2. Just finished for the dev environment, for the prod environment you do the same but change the word dev to prod

  3. Repeat the Oath key generation the same number of times as the environment you created. I only have 2 environments so I only generate 2 keys, if you have 3, or 5, feel free to create

  4. Make sure you add enough SHA1 and SHA-256 to your project when doing those step

  5. That is.

  • Related