Description:
I am facing an issue only on Android apps in which the IDToken returned by Firebase is invalid. [Flutter]
However, I tested on web app, the IDToken is working fine.
Not sure if I am retrieving the IDToken correctly.
Below are the error code and my code portion to retrieve the IDToken.
Error Code:
{
"error": "failed to verify token signature",
"code": 16,
"type": "Unauthenticated"
}
How I Retrieve The IDToken:
Future<FirebaseUser> loginWithFacebook() async {
final FacebookLoginResult facebookLoginResult =
await facebookLogin.logIn(<String>['email', 'public_profile']);
final FacebookAccessToken myToken = facebookLoginResult.accessToken;
final AuthCredential credential =
FacebookAuthProvider.getCredential(accessToken: myToken.token);
final FirebaseUser firebaseUser =
(await FirebaseAuth.instance.signInWithCredential(credential)).user;
final FirebaseUser user = await FirebaseAuth.instance.currentUser();
final IdTokenResult idToken = await user.getIdToken();
globalBloc.setName(firebaseUser.displayName);
globalBloc.setEmail(firebaseUser.email);
globalBloc.setProfilePictureUrl(firebaseUser.photoUrl);
print('----------------Firebase ID Token----------------');
print('Facebook: ${myToken.token}');
print(idToken.token);
print(idToken.authTime);
print(idToken.claims);
print(idToken.signInProvider);
print('----------------Firebase ID Token----------------');
}
Additional Information:
firebase_auth: ^0.16.0
flutter_facebook_login: ^3.0.0
Flutter Doctor:
[✓] Flutter (Channel stable, v1.17.3, on Mac OS X 10.15.4 19E287, locale en-MY)
• Flutter version 1.17.3 at /Users/rm1025/Downloads/flutter
• Framework revision b041144f83 (4 days ago), 2020-06-04 09:26:11 -0700
• Engine revision ee76268252
• Dart version 2.8.4
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.0)
• Android SDK at /Users/rm1025/Library/Android/sdk
• Platform android-29, build-tools 29.0.0
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 11.5)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 11.5, Build version 11E608c
• CocoaPods version 1.8.4
[✓] Android Studio (version 3.6)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin version 42.1.1
• Dart plugin version 191.8593
• Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)
[✓] VS Code (version 1.45.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.11.0
[✓] Connected device (1 available)
• AOSP on IA Emulator • emulator-5554 • android-x86 • Android 9 (API 28) (emulator)
• No issues found!
Hi @heartsdales
Using
firebase_auth: ^0.16.1
firebase_core: ^0.4.5
google_sign_in: ^4.5.1
Code Sample
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
theme: ThemeData.dark(),
home: Home(),
);
}
}
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
final GoogleSignIn _googleSignIn = GoogleSignIn();
final FirebaseAuth _auth = FirebaseAuth.instance;
String userName;
bool iSignedIn = false;
@override
void initState() {
super.initState();
getFirebaseUser();
}
Future<FirebaseUser> _handleSignIn() async {
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
final FirebaseUser user =
(await _auth.signInWithCredential(credential)).user;
print("signed in " + user.displayName);
user.getIdToken().then((value) {
print("Token ${value.token}");
});
setState(() {
userName = user.displayName;
iSignedIn = true;
});
return user;
}
Future<FirebaseUser> getFirebaseUser() async {
FirebaseUser firebaseUser = await FirebaseAuth.instance.currentUser();
if (firebaseUser == null) {
firebaseUser = await FirebaseAuth.instance.onAuthStateChanged.first;
}
if (firebaseUser != null) {
firebaseUser.getIdToken().then((value) {
print("Token ${value.token}");
});
setState(() {
userName = firebaseUser?.displayName;
iSignedIn = true;
});
}
return firebaseUser;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Material App Bar'),
),
body: Center(
child: Container(
child: Text(iSignedIn ? userName : 'empty user name'),
),
),
floatingActionButton: FloatingActionButton.extended(
icon: Icon(Icons.add),
label: Text(iSignedIn ? 'Sign Out' : 'Sign In'),
onPressed: () {
if (!iSignedIn) {
_handleSignIn();
} else {
_auth.signOut();
setState(() {
iSignedIn = false;
});
}
},
),
);
}
}
After sign in, it prints token id
Thank you
Future
_handleSignIn() async {
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;final AuthCredential credential = GoogleAuthProvider.getCredential( accessToken: googleAuth.accessToken, idToken: googleAuth.idToken, ); final FirebaseUser user = (await _auth.signInWithCredential(credential)).user; print("signed in " + user.displayName); user.getIdToken().then((value) { print("Token ${value.token}"); }); setState(() { userName = user.displayName; iSignedIn = true; }); return user;}
Future
getFirebaseUser() async {
FirebaseUser firebaseUser = await FirebaseAuth.instance.currentUser();
if (firebaseUser == null) {
firebaseUser = await FirebaseAuth.instance.onAuthStateChanged.first;
}if (firebaseUser != null) { firebaseUser.getIdToken().then((value) { print("Token ${value.token}"); }); setState(() { userName = firebaseUser?.displayName; iSignedIn = true; }); } return firebaseUser;}
Hi Sir,
Thank you for your response.
I had tested with the sample you provided, unfortunately, I'm am still facing the same issue, still getting the same error code.
Not sure it is caused by the code on my backend side or what.
Might need your further advice.
Hi @heartsdales
Make sure your google account is showing in firebase console authentications -> users
Hi @heartsdales
Make sure your google account is showing in firebase console authentications -> users
Yes it is showing there.
Hi @TahaTesser, we were working in the same project. It does print ID Token, but unable to verify from custom backend with Firebase Admin SDK. It returns failed to verify token signature from Firebase Admin SDK.
Initially we thought was Admin SDK issue, and we tested with Web SDK to retrieve Firebase ID Token, and it was able to verify from Admin SDK. Only ID Token from FlutterFire has the error.
All related providers have been enabled from Firebase Console, tested and run well with Web SDK.
We also suspect the Android App doesn't added correctly, and tried to re-add our app too.
However, we can reproduce this error, by randomly delete some characters of ID Token retrieved from Web SDK, and get the exact same error message, failed to verify token signature. I suspect there are some characters truncated when retrieving ID Token with FlutterFire.
Having the same problem here, JWT tokens from generated from firebase_auth Flutter library cannot be verified properly on our backend server in Python using the firebase-admin package
Hi just an update, we finally isolated the problem to the Android version of the app only. Testing the same app on iOS works perfectly on our server.
The reason is totally unrelated to this library - debugPrint() in Flutter/Dart on the Android platform does not have enough buffer to print out the entire token string. I suggest closing this issue.
Hi, I am facing the exact same issue, the token we getting after user successfully authenticate, not being verified on BE. Did anyone manage to narrow down the root cause for this?
Not sure if it's related, but while using firebase_auth: ^0.18.0-dev.2 on Flutter Web, the following command logged me in.
try {
credential = GoogleAuthProvider.credential(
accessToken: googleAuth.idToken,
idToken: googleAuth.idToken,
);
} catch (e) {
print(e);
}
Which obviously doesn't make sense but it seems that accessToken is null and idToken is actually accessToken in Web...
In iOS which I just tested,
credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
works like a charm.
Hey 👋
Our rework of the firebase_auth plugin as part of the FlutterFire roadmap was published over a week ago with a ton of fixes and new features. Please could you try the new version and see if this is still an issue for you? If it is then please submit a new up to date GitHub issue.
Also see: https://github.com/FirebaseExtended/flutterfire/issues/2728#issuecomment-663430046
For help migrating to the new plugins please see the new migration guide: https://firebase.flutter.dev/docs/migration
Most helpful comment
Hi @TahaTesser, we were working in the same project. It does print ID Token, but unable to verify from custom backend with Firebase Admin SDK. It returns
failed to verify token signaturefrom Firebase Admin SDK.Initially we thought was Admin SDK issue, and we tested with Web SDK to retrieve Firebase ID Token, and it was able to verify from Admin SDK. Only ID Token from FlutterFire has the error.
All related providers have been enabled from Firebase Console, tested and run well with Web SDK.
We also suspect the Android App doesn't added correctly, and tried to re-add our app too.
However, we can reproduce this error, by randomly delete some characters of ID Token retrieved from Web SDK, and get the exact same error message,
failed to verify token signature. I suspect there are some characters truncated when retrieving ID Token with FlutterFire.