10

I am trying to learn how to get a flutter app to login to firebase auth. I've created a new flutter project using the android studio plugin and added the dependencies and code from the firebase_auth page.

I'm getting the error "The method 'signInWithGoogle' isn't defined for the class 'FirebaseAuth'" when trying to call the method in the FirebaseAuth.instance (_auth). Here's the code:

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  final GoogleSignIn _googleSignIn = GoogleSignIn();
  final FirebaseAuth _auth = FirebaseAuth.instance;

  Future<FirebaseUser> _handleSignIn() async {
    GoogleSignInAccount googleUser = await _googleSignIn.signIn();
    GoogleSignInAuthentication googleAuth = await googleUser.authentication;
    FirebaseUser user = await _auth.signInWithGoogle(
      accessToken: googleAuth.accessToken,
      idToken: googleAuth.idToken,
    );
    print("signed in " + user.displayName);
    return user;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: <Widget>[      // Add 3 lines from here...
          new IconButton(icon: const Icon(Icons.mic), onPressed: () {
            _handleSignIn()
                .then((FirebaseUser user) => print(user))
                .catchError((e) => print(e));
          })
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

Pubspec.yaml:

name: flutter_auth
description: Trying out firebase_auth

version: 1.0.0+1

environment:
  sdk: ">=2.0.0-dev.68.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^0.1.2

  google_sign_in: ^4.0.0
  firebase_auth: ^0.8.0+1

dev_dependencies:
  flutter_test:
    sdk: flutter


flutter:

  uses-material-design: true
T. Cervenka
  • 301
  • 1
  • 2
  • 11
  • Does this answer your question? [Flutter Firebase.signInWithGoogle method not found](https://stackoverflow.com/questions/54508591/flutter-firebase-signinwithgoogle-method-not-found) – Alexandre Jean Nov 07 '19 at 01:35

7 Answers7

14

I had the same problem and found the example in the firebase_auth

https://github.com/flutter/plugins/blob/master/packages/firebase_auth/example/lib/main.dart

Try replacing your handleSignIn method with

  Future<FirebaseUser> _handleSignIn() async {
    GoogleSignInAccount googleUser = await _googleSignIn.signIn();
    GoogleSignInAuthentication googleAuth = await googleUser.authentication;
    final AuthCredential credential = GoogleAuthProvider.getCredential(
      accessToken: googleAuth.accessToken,
      idToken: googleAuth.idToken,
    );
    final FirebaseUser user = await _auth.signInWithCredential(credential);
    print("signed in " + user.displayName);
    return user;
  }

It may be that the signInWithGoogle method is valid but I couldn't find anything on it and the above code works for me.

Paul
  • 158
  • 1
  • 6
  • That solved the compilation problem. At runtime I am able to authenticate with the google account but now this method throws 'PlatformException(sign_in_failed, com.google.android.gms.common.api.ApiException: 16: , null)' – T. Cervenka Jan 31 '19 at 22:21
  • That turned out to be a config problem. Problem solved. Thanks, Paul. – T. Cervenka Jan 31 '19 at 22:43
  • @T.Cervenka which config problem was that and how did you solve it?? Because I also get the same exception at runtime – lorrainemutheu Jun 09 '19 at 19:49
  • Sorry, can't remember exactly what was wrong. I've found so many config issues for flutter/firebase_auth that I made notes that I'd be happy to send to you if you send an mail to me at tom@cervenka.org – T. Cervenka Jun 28 '19 at 15:26
  • 1
    `_auth.signInWithCredential` returns `Future`. – Nimish David Mathew Oct 29 '19 at 09:58
  • As @Nimish David Mathew said, it returns the result, so it might be: final result = await _auth.signInWithCredential(credential); final user = result.user; – Hyung Tae Carapeto Figur Aug 12 '20 at 23:24
9

This implementation has been changed again, so now the _auth.signInWithCredential returns an AuthResult instance, and you can access to the user as a property of this object.

Future<FirebaseUser> _handleSignIn() async {
  GoogleSignInAccount googleUser = await _googleSignIn.signIn();
  GoogleSignInAuthentication googleAuth = await googleUser.authentication;
  final AuthCredential credential = GoogleAuthProvider.getCredential(
    accessToken: googleAuth.accessToken,
    idToken: googleAuth.idToken,
  );
  final AuthResult authResult = await _auth.signInWithCredential(credential);
  FirebaseUser user = authResult.user;
  print("signed in " + user.displayName);
  return user;
}
3

For Flutter 2.0

  final GoogleSignInAccount googleUser = await GoogleSignIn().signIn();
  final GoogleSignInAuthentication googleAuth = await googleUser.authentication;

  await firebaseAuth.signInWithGoogle(idToken: googleAuth.accessToken, accessToken: googleAuth.idToken);
  • 1
    This is the answer that worked for me - this seems to be a new minor breaking change where you need to await the signIn() method and explicitly type the two finals for the googleUser and googleAuth – Erik White May 06 '21 at 18:31
1

This answer was copied from here: Undefined class 'FirebaseUser'

Starting from Version firebase_auth 0.18.0:

In the newest version of firebase_auth, the class FirebaseUser was changed to User, and the class AuthResult was changed to UserCredentail. Therefore change your code to the following:

Future<User> currentUser() async {
  final GoogleSignInAccount account = await googleSignIn.signIn();
  final GoogleSignInAuthentication authentication =
      await account.authentication;

  final GoogleAuthCredential credential = GoogleAuthProvider.credential(
      idToken: authentication.idToken,
      accessToken: authentication.accessToken);

  final UserCredential authResult =
      await _auth.signInWithCredential(credential);
  final User user = authResult.user;

  return user;
}

FirebaseUser changed to User

AuthResult changed to UserCredential

GoogleAuthProvider.getCredential() changed to GoogleAuthProvider.credential()

onAuthStateChanged which notifies about changes to the user's sign-in state was replaced with authStateChanges()

currentUser() which is a method to retrieve the currently logged in user, was replaced with the property currentUser and it no longer returns a Future<FirebaseUser>.

Example of the above two methods:

FirebaseAuth.instance.authStateChanges().listen((event) {
   print(event.email);
});

And:

var user = FirebaseAuth.instance.currentUser;
print(user.uid);
Xander Selorm
  • 558
  • 6
  • 18
0

this is a method to sign in with google auth

Future<FirebaseUser> signInWithGoogle() async {
final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
final GoogleSignInAuthentication googleSignInAuthentication =
    await googleSignInAccount.authentication;

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

final AuthResult authResult =
    await _firebaseAuth.signInWithCredential(credential);
final FirebaseUser user = authResult.user;

final FirebaseUser currentUser = await _firebaseAuth.currentUser();
if (currentUser != null) {
  final QuerySnapshot result = await Firestore.instance
      .collection('users')
      .where("id", isEqualTo: currentUser.uid)
      .getDocuments();
  final List<DocumentSnapshot> document = result.documents;
  if (document.length == 0) {
    Firestore.instance
        .collection('users')
        .document(currentUser.uid)
        .setData({
      'id': currentUser.uid,
      'username': currentUser.displayName,
      'profilePicture': currentUser.photoUrl
    });
  } else {}
}
return user;

}

Usama Elgendy
  • 506
  • 4
  • 8
0
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';

final FirebaseAuth _auth = FirebaseAuth.instance;
final GoogleSignIn googleSignIn = GoogleSignIn();

Future<String> signInWithGoogle() async {
  final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
  final GoogleSignInAuthentication googleSignInAuthentication =
      await googleSignInAccount.authentication;

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

  final AuthResult authResult = await _auth.signInWithCredential(credential);
  final FirebaseUser user = authResult.user;

  assert(!user.isAnonymous);
  assert(await user.getIdToken() != null);

  final FirebaseUser currentUser = await _auth.currentUser();
  assert(user.uid == currentUser.uid);

  return 'signInWithGoogle succeeded: $user';
}

follow this approach which simple and best in my point view

0

Just Initialize GoogleSignIn with FirebaseAuth globally

final GoogleSignIn _googleSignIn = GoogleSignIn();
final FirebaseAuth _auth = FirebaseAuth.instance;

use _googleSignIn wherever you have written GoogleSignIn().signIn()

final GoogleSignInAccount googleUser = await _googleSignIn.signIn();