Create OAuthCredential with OAuthProvider for 3rd party provider in Flutter firebase_auth (LINE login)

Viewed 185

Pasting the issue I just opened in the firebase_auth github repo here in case someone here has a better idea as to what's going on:

I am trying to pass in an identity token and/or access token to the OAuthProvider().credential() method in order to link a user logging in with LINE to an anonymous user created at app launch, but receiving the error:

flutter: [firebase_auth/internal-error] An internal error has occurred, print and inspect the error details for more information.
flutter: Error code: internal-error

Steps to reproduce

I'm not exactly how to share steps to produce the behavior, since they require using the flutter_line_sdk package from pub.dev to obtain the LINE user's access/id tokens for auth purposes, which is lengthy and involves private/confidential information. However, hopefully the sample code below can help with troubleshooting.

Expected behavior

I expect for:

oAuthCredential = OAuthProvider("line.com").credential(
      idToken: myLineUserIdToken
     # and/or!
      accessToken: myLineUserAccessToken,
);

to return an OAuthCredential as it does with Sign in With Apple that I can pass into:

 userCredential = await _user.linkWithCredential(oAuthCredential);

Sample project

the _user variable below is a reference to the currently/previously logged in anonymous user that is created at app launch.

final loginResult = await line.login(scopes: [
        "profile",
        "openid",
        "email",
      ]);

      UserCredential userCredential;
      final verificationResult = await line.verifyAccessToken();

if (verificationResult.data != null) {
        final idToken = loginResult.accessToken.idToken;
        final idTokenRaw = loginResult.accessToken.idTokenRaw;

OAuthCredential oAuthCredential;
try {
          print('===== ID TOKEN (RAW) =====');
          print(idTokenRaw);
          print('===== ACCESS TOKEN =====');
          print(loginResult.accessToken.data["access_token"]);
          print('===== _user IS ANONYMOUS =====');
          print(_user.isAnonymous);

          oAuthCredential = OAuthProvider("line.com").credential(
              idToken: loginResult.accessToken.idTokenRaw,
              accessToken: loginResult.accessToken.data["access_token"]);
          userCredential = await _user.linkWithCredential(oAuthCredential);
        } on FirebaseAuthException catch (e, s) {
          print('Error linking LINE cred to anonymous credential:');
          print('\n$e\nstack:$s');
          print('Error code: ${e.code}');
       }
}

Outputs:

flutter: ===== ID TOKEN (RAW) =====
flutter: my.LineAuthIdToken.jwt
flutter: ===== ACCESS TOKEN =====
flutter: my.LineAuthAccessToken.jwt
flutter: ===== _user IS ANONYMOUS =====
flutter: true
flutter: [firebase_auth/internal-error] An internal error has occurred, print and inspect the error details for more information.
stack:#0      MethodChannelUser.linkWithCredential
package:firebase_auth_platform_interface/…/method_channel/method_channel_user.dart:98
<asynchronous suspension>
#1      User.linkWithCredential
package:firebase_auth/src/user.dart:185
<asynchronous suspension>
#2      LineAuthService.signInWithLine
package:wordbud/auth/line_auth_service.dart:94
(^this line is referencing the code above `userCredential = await _user.linkWithCredential(oAuthCredential);`^)
<asynchronous suspension>
#3      _LoginState._buildLineButton.<anonymous closure>
package:wordbud/…/onboarding/login.dart:268
<asynchronous suspension>
flutter: Error code: internal-error

Additional context

I know that both the access token and the id token I have tried using (I tried just one, just the other, and both passed in as arguments to the .credential method to no avail) are valid, because I have successfully used them to create a custom token in a firebase cloud function and sign in users through that method. However that doesn't allow me to link the newly signed in LINE user to the previous anonymous user and capture some firestore data linked to the anonymous user.

Your documentation for the OAuthProvider class states:

A generic provider instance.

This class is extended by other OAuth based providers, or can be used standalone for integration with other 3rd party providers.

This to me seems to state the class is there specifically for scenarios such as mine. The Auth flow using the flutter_line_sdk doesn't differ from Apple in any meaningful way, and provides all of the same tokens needed for any OAuth process.


Flutter doctor

flutter doctor output:

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.5.3, on macOS 11.6 20G165 darwin-x64, locale en)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 2020.3)
[✓] VS Code (version 1.62.3)
[✓] Connected device (4 available)
    ! Error: iPhone 13 Pro Max is busy: Fetching debug symbols for iPhone 13 Pro Max. Xcode will continue when iPhone 13 Pro Max is finished. (code -10)

• No issues found!

Flutter dependencies

flutter pub deps -- --style=compact relevant output:

(My team's app is quite large and also confidential so I only pasted packages imported in the file I'm referencing code from)

Dart SDK 2.14.4
Flutter SDK 2.5.3

dependencies:
- flutter_line_sdk 2.1.0 [flutter]
- firebase_auth 3.2.0 [firebase_auth_platform_interface firebase_auth_web firebase_core firebase_core_platform_interface flutter meta]
- firebase_core 1.10.0 [firebase_core_platform_interface firebase_core_web flutter meta]
- cloud_firestore 3.1.0 [cloud_firestore_platform_interface cloud_firestore_web collection firebase_core firebase_core_platform_interface flutter meta]

0 Answers
Related