iTranslated by AI
Implementing Authentication in Flutter with Firebase and Google Sign-In
Introduction
Building authentication from scratch is a significant undertaking.
Furthermore, if you are not confident in your security expertise, it is often better to avoid building it yourself. (Anything published on the internet will be subjected to relentless attacks.)
Firebase Authentication is one of the features provided by Firebase.
It provides not only email and password-based authentication but also authentication integrated with Google and Facebook.
Using Firebase Authentication makes it easy to build a login function simply and securely.
In this article, I will explain how to implement a login function in Flutter using Firebase Authentication and a Google account.
Prerequisites (Firebase Authentication)
In this implementation, we will use Google account sign-in.
Before you can use the sign-in method, you need to configure it in the Firebase console.
First, access Firebase > Authentication and click the "Set up sign-in method" button.
To enable login with a Google account, turn on Google > Enable.
The project public-facing name is the project name shown to users, such as in Google security notifications when logging into the service (e.g., "Access to your Google Account was granted to <project public name>").
Set an email address for the project support email and click Save.
Finally, check the status of Google; if it is "Enabled," you are all set.
Prerequisites (Flutter)
In this implementation, we will use the following packages.
dependencies:
flutter:
sdk: flutter
firebase_core: ^0.4.2+1
firebase_auth: ^0.15.1
google_sign_in: ^4.0.14
flutter_signin_button: ^1.1.0
After adding these to pubspec.yaml, install them using flutter pub get.
Additionally, for this setup, you need to configure the Google Sign-in part.
google_sign_in | Flutter Package
According to the official site, add CFBundleTypeRole and CFBundleURLSchemes to Info.plist.
For CFBundleURLSchemes, copy and paste the REVERSED_CLIENT_ID key from GoogleService-Info.plist into the array>string section.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<!-- TODO Copy the REVERSED_CLIENT_ID key from GoogleService-Info.plist and
replace the value here -->
<string>com.googleusercontent.apps.861823949799-xxxxxxxxxxxxxxxxxxxxxxxxx</string>
</array>
</dict>
</array>
Note that if there is a mistake in this configuration (such as formatting), the app will crash with the following error when using the google_sign_in plugin:
Failed to send request: {"jsonrpc":"2.0","id":"100","method":"getStack","params":{"isolateId":"isolates/392598366557863"}}
Failed to send request: {"jsonrpc":"2.0","id":"101","method":"getObject","params":{"isolateId":"isolates/392598366557863","objectId":"classes/3284"}}
Failed to send request: {"jsonrpc":"2.0","id":"102","method":"invoke","params":{"isolateId":"isolates/392598366557863","targetId":"objects/629","selector":"toString","argumentIds":[],"disableBreakpoints":true}}
Looking at the detailed logs, an error is occurring in the URL schemes section.
$ flutter run -verbose
...
...
[+26526 ms] flutter: Exception
[ ] flutter: PlatformException(google_sign_in, Your app is missing support for the following URL schemes: com.googleusercontent.apps.480616290440-xxxxxxxxxxxxxxxxxxxxxxxx, NSInvalidArgumentException, null)
[ +17 ms] Service protocol connection closed.
[ ] Lost connection to device.
[ +3 ms] DevFS: Deleting filesystem on the device (hogehoge)
[ +257 ms] Ignored error while cleaning up DevFS: TimeoutException after 0:00:00.250000: Future not completed
[ +1 ms] "flutter run" took 134,429ms.
[ +2 ms] ensureAnalyticsSent: 0ms
[ ] Running shutdown hooks
[ ] Shutdown hook priority 4
[ +1 ms] Shutdown hooks complete
[ ] exiting with code 0
In Xcode, check TARGETS > Info > URL Types. If no values are displayed, the configuration is incorrect, so fix it properly (you can do this directly in Xcode).
(Setup guide: IOS : Login google Crash : ‘Your app is missing support for the following URL schemes: com.googleusercontent.app’ | by TungShien.com | CodeSpace69 | Medium )
Implementation (Flutter)
Now that the preparations are complete, let's move on to the implementation.
First, make the main function an async function and initialize Firebase.
Future<void> main() async {
// Add these two lines
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(SignInDemoApp());
}
Next, prepare a widget like the following:
class SignInDemo extends StatefulWidget {
@override
State createState() => SignInDemoState();
}
class SignInDemoState extends State<SignInDemo> {
final _auth = FirebaseAuth.instance;
@override
Widget build(BuildContext context) {
return Scaffold();
}
}
At this point, I encountered a build error like the following:
Error: CocoaPods's specs repository is too out-of-date to satisfy dependencies.
To update the CocoaPods specs, run:
pod repo update
Error running pod install
Error launching application on iPad Pro (12.9-inch) (4th generation).
[!] CocoaPods could not find compatible versions for pod "Firebase/CoreOnly":
In snapshot (Podfile.lock):
Firebase/CoreOnly (= 6.26.0, ~> 6.26.0)
In Podfile:
cloud_firestore (from `.symlinks/plugins/cloud_firestore/ios`) was resolved to 0.14.1-3, which depends on
Firebase/CoreOnly (~> 6.33.0)
You have either:
* changed the constraints of dependency `Firebase/CoreOnly` inside your development pod `cloud_firestore`.
You should run `pod update Firebase/CoreOnly` to apply changes you've made.
It seems like CocoaPods is failing to resolve dependencies, and the troubleshooting steps suggested in the error screen (such as pod repo update) did not resolve it.
I was able to solve it using the following method:
cd <Flutter Project>
cd ios
rm Podfile.lock
pod install --repo-update
cd ..
flutter clean
Next, implement the login part using a Google account.
You can sign in by calling the following signInWithGoogle() from a sign-in button.
// Sign in with Google
Future<UserCredential> signInWithGoogle() async {
// Trigger the authentication flow
final googleUser = await GoogleSignIn(scopes: [
'email',
]).signIn();
// Obtain authentication information from the request
final googleAuth = await googleUser.authentication;
// Create a new credential
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
// Return UserCredential once signed in
return FirebaseAuth.instance.signInWithCredential(credential);
}
The side calling signInWithGoogle() looks like this:
onPressed: () async {
try {
final userCredential = await signInWithGoogle();
} on FirebaseAuthException catch (e) {
print('FirebaseAuthException');
print('${e.code}');
} on Exception catch (e) {
print('Other Exception');
print('${e.toString()}');
}
}
Finally, build the app, and you will be able to log in.
Also, the full code is available here:
FirebaseAuthentication demo using Google Sign-in in Flutter.
Results
First, a screen like this will appear. Click "Sign in with Google" to proceed with the login.
As you proceed with the login, a screen like the following might appear at this time, but click on "Show details" > "Go to (unsafe page)".
After that, follow the prompts to confirm, and you will be logged in.
References
Authentication | FlutterFire
Social Authentication | FlutterFire
The OAuth 2.0 Authorization Framework
OAuth 2.0 Scopes for Google APIs | Google Identity Platform
[google_sign_in] Google sign in crashes the flutter app in IOS device · Issue #44564 · flutter/flutter
IOS : Login google Crash : ‘Your app is missing support for the following URL schemes: com.googleusercontent.app’ | by TungShien.com | CodeSpace69 | Medium
ちょっとでもセキュリティに自信がないなら、 Firebase Authentication を検討しよう - mizdev
Discussion