skip to Main Content

I need to do google signin in flutter app using firebase. Generate idToken at client, and send it to backend Admin SDK for verification of idToken.

Issue: I am getting below error when calling method of Firebase Admin SDK.
FirebaseAuth.getInstance(firebaseApp).verifyIdToken(clientIdToken);

error:


com.google.firebase.auth.FirebaseAuthException: Failed to parse Firebase ID token. Make sure you passed a string that represents a complete and valid JWT. See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.

    at com.google.firebase.auth.FirebaseTokenVerifierImpl.newException(FirebaseTokenVerifierImpl.java:237)
    at com.google.firebase.auth.FirebaseTokenVerifierImpl.parse(FirebaseTokenVerifierImpl.java:153)
    at com.google.firebase.auth.FirebaseTokenVerifierImpl.verifyToken(FirebaseTokenVerifierImpl.java:99)
    at com.google.firebase.auth.AbstractFirebaseAuth$3.execute(AbstractFirebaseAuth.java:307)
    at com.google.firebase.auth.AbstractFirebaseAuth$3.execute(AbstractFirebaseAuth.java:304)
    at com.google.firebase.internal.CallableOperation.call(CallableOperation.java:36)
    at com.google.firebase.auth.AbstractFirebaseAuth.verifyIdToken(AbstractFirebaseAuth.java:269)
    at com.google.firebase.auth.AbstractFirebaseAuth.verifyIdToken(AbstractFirebaseAuth.java:241)
    at com.dummy.poc.firebase.FirebaseApplicationTests.contextLoads(FirebaseApplicationTests.java:45)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
    at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
    at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
    at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: java.lang.IllegalArgumentException: com.google.common.io.BaseEncoding$DecodingException: Invalid input length 153
    at com.google.common.io.BaseEncoding.decode(BaseEncoding.java:218)
    at com.google.api.client.util.Base64.decodeBase64(Base64.java:106)
    at com.google.api.client.json.webtoken.JsonWebSignature$Parser.parse(JsonWebSignature.java:551)
    at com.google.api.client.auth.openidconnect.IdToken.parse(IdToken.java:155)
    at com.google.firebase.auth.FirebaseTokenVerifierImpl.parse(FirebaseTokenVerifierImpl.java:143)
    ... 76 more
Caused by: com.google.common.io.BaseEncoding$DecodingException: Invalid input length 153
    at com.google.common.io.BaseEncoding$Base64Encoding.decodeTo(BaseEncoding.java:968)
    at com.google.common.io.BaseEncoding.decodeChecked(BaseEncoding.java:233)
    at com.google.common.io.BaseEncoding.decode(BaseEncoding.java:216)
    ... 80 more

Client code:
pubsec.yml

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  provider: ^6.0.0
  google_sign_in: ^5.0.7
  firebase_core: ^1.6.0
  firebase_auth: ^3.1.1

ControllerLogin.dart

allowUserLoginWithGoogle() async{
    UserCredential credential  = await signInWithGoogle();

    print('in allowUserLoginWithGoogle after google sign in');

    User? user = credential.user;

    String? idToken = await user?.getIdToken();  // I have tried for this idToken verification also. getting same error but instead of 153 getting 157

    User? mUser = await FirebaseAuth.instance.currentUser;
    var mUserIdToken = await mUser?.getIdToken(); // I am sending this IdToken to backend for verification and getting error on verifying the same.

    notifyListeners();
  }

Future<UserCredential> signInWithGoogle() async {
    final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn();

    final GoogleSignInAuthentication? googleAuth = await googleUser?.authentication;

    final credential = GoogleAuthProvider.credential(
      accessToken: googleAuth?.accessToken,
      idToken: googleAuth?.idToken,
    );

    await Firebase.initializeApp();

    return await FirebaseAuth.instance.signInWithCredential(credential);
  }

Backend verify id token code

public FirebaseApp firebaseApp() throws Exception {
        FileInputStream serviceAccount =
                new FileInputStream("/Users/anonymous/Documents/app/poc/firebase/src/main/java/com/dummy/poc/firebase/auth-test-project-b0c91-firebase-adminsdk-vrz4u-ab7b3962b0.json");

        FirebaseOptions options = new FirebaseOptions.Builder()
                .setCredentials(GoogleCredentials.fromStream(serviceAccount))
                .build();

        return FirebaseApp.initializeApp(options);
}

@Test
void contextLoads() throws Exception {
    String mUserIdToken = <id token from client>;
    FirebaseToken firebaseToken
    FirebaseAuth.getInstance(firebaseApp()).verifyIdToken(mUserIdToken); // this line is giving me above error
}

I have tried verifying the idToken on jwt.io. There I am able to decode the jwt token although it shows invalid signature but the token is getting decoded on jwt.io
Please help.

2

Answers


  1. Chosen as BEST ANSWER

    It's absolutely my mistake. I was not knowing the difference between access token and idToken and also diff between Oauth2 and OIDC. later after reading about these concepts, I am able to resolve it.

    Basically, what I was trying to do is create accessToken using firebase and pass it to verifyIdToken which was wrong.

    Later when I have written a web application and received a idToken by google login using firebase and passed it to this method at backend it worked.


  2. I don’t know how but, your id token string is not passed fully, make sure you are passing whole string of Id token.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search