**I didn't explain how to create a project in Firebase

Solution

  • I have a signInWithGoogle method like this:
darts
        
  ...
  
  Future<UserCredential?> signInWithGoogle() async {
    try {
      final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
      
      if (googleUser == null) {
        return null;
      }

      final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
      final OAuthCredential credential = GoogleAuthProvider.credential(
        accessToken: googleAuth.accessToken,
        idToken: googleAuth.idToken,
      );

      return await _auth.signInWithCredential(credential);
    } on FirebaseAuthException catch (e) {
      throw _handleAuthException(e);
    }
  }

  ...
      
  • Then in the event button login with Google:
darts
        
  ...
  
  onPressed: () async {
    final currentContext = context;

    final userCredential = await AuthService().signInWithGoogle();
    if (userCredential != null) {
      final user = userCredential.user;
      final idToken = await user!.getIdToken();

      // send user data to backend
      final response = await http.post(
        Uri.parse('${dotenv.env['API_URL']}/api/v1/auth/google-login'), // backend url
        headers: {'Content-Type': 'application/json'},
        body: json.encode({
          'id_token': idToken,
        }),
      );

      if (currentContext.mounted) {
        if (response.statusCode == 200) {
          authService.setUserCredential(userCredential);
          // redirect to home
          Navigator.of(context).pushReplacementNamed('/home');
        } else {
          // show error message
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Text('Login failed. Please try again.'),
            ),
          );
        }
      }
    }
  }
  ...
      
  • Meanwhile on my Django server, I use the google-auth library to validate Firebase tokens:
python
        
from google.oauth2 import id_token
from google.auth.transport import requests
import json
import random
from .models import Account

...

def google_login(request):
    data = json.loads(request.body)
    token = data['id_token']

    try:
        #CLIENT_ID = 'xxxx.apps.googleusercontent.com'
        # idinfo = id_token.verify_oauth2_token(token, requests.Request(), CLIENT_ID)
        idinfo = id_token.verify_firebase_token(token, requests.Request())

        email = idinfo['email']
        username = idinfo['name']

        user, created = Account.objects.get_or_create(
            account_email=email,
            defaults={
                'account_id': random.randint(10**10, 10**11 - 1),
                'username': username,
                'login_with': 'GOOGLE',
                'active_status': True
            }
        )
      
  • the commented part is the code I got from AI, but it doesn't work. I searched for a solution for quite a long time and finally I found a solution from reference. I changed id_token.verify_oauth2_token to id_token.verify_firebase_token and it worked. So for tokens obtained from Firebase, we have to use verify_firebase_token not verify_oauth2_token.

Reference

https://github.com/googleapis/google-auth-library-python/issues/316#issuecomment-667777124