aboutyou / dart_packages

Dart and Flutter plugins maintained and used by @ABOUTYOU
222 stars 150 forks source link

sign_in_with_apple: MISSING_ACTIVITY error on Android #73

Closed dluksza closed 4 years ago

dluksza commented 4 years ago

I can't get it working on Android with Flutter 1.17.0 (I'm on beta channel) and plugin version 2.1.0

Here is how authentication is requested:

class AppleAuthService {
  Future<AuthorizationCredentialAppleID> signIn(String nonce) {
    return SignInWithApple.getAppleIDCredential(
      scopes: [AppleIDAuthorizationScopes.email],
      webAuthenticationOptions: _getOptions(),
      nonce: nonce,
    );
  }

  WebAuthenticationOptions _getOptions() {
    if (Platform.isIOS) {
      return null;
    }
    return WebAuthenticationOptions(
      clientId: _clientId,
      redirectUri: UriData.fromString(_webUrl).uri,
    );
  }
}

I see sign_in_with_apple being registered in GeneratedPluginRegistrant.java (yes, my android project is still in java). Any hints what may causing this error?

HenriBeck commented 4 years ago

@dluksza Could you please provide more info.

dluksza commented 4 years ago

What is your _webUrl? https://habitchallenge-dev.firebaseapp.com/__/auth/handler'

Are you testing this on an Emulator or a real Device?

I've tested it on emulator and oneplus 5 both in debug mode.

Do you have a full native stack trace from the device so we can know where this error actually originated?

Actually didn't checked the logcat ealier. Now I do see an exception over there:

2020-05-06 22:06:04.337 3550-3579/? W/ziparchive: Unable to open '/data/app/org.luksza.HabitChallenge.dev-QhBOJOe_r1y8E5XL0WWX1A==/base.apk': No such file or directory
2020-05-06 22:06:04.337 3550-3579/? E/neplus.launche: Failed to open APK '/data/app/org.luksza.HabitChallenge.dev-QhBOJOe_r1y8E5XL0WWX1A==/base.apk' I/O error
2020-05-06 22:06:04.337 3550-3579/? E/ResourcesManager: failed to add asset path /data/app/org.luksza.HabitChallenge.dev-QhBOJOe_r1y8E5XL0WWX1A==/base.apk
2020-05-06 22:06:04.337 3550-3579/? W/PackageManager: Failure retrieving resources for org.luksza.HabitChallenge.dev
2020-05-06 22:06:04.389 1358-1358/? E/LoadedApk: Unable to instantiate appComponentFactory
    java.lang.ClassNotFoundException: Didn't find class "androidx.core.app.CoreComponentFactory" on path: DexPathList[[],nativeLibraryDirectories=[/data/app/org.luksza.HabitChallenge.dev-Ls9oScDYgr1O8MHW6FSV7A==/lib/arm64, /data/app/org.luksza.HabitChallenge.dev-Ls9oScDYgr1O8MHW6FSV7A==/base.apk!/lib/arm64-v8a, /system/lib64]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        at android.app.LoadedApk.createAppFactory(LoadedApk.java:226)
        at android.app.LoadedApk.updateApplicationInfo(LoadedApk.java:346)
        at android.app.ActivityThread.handleDispatchPackageBroadcast(ActivityThread.java:5534)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1841)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at com.android.server.SystemServer.run(SystemServer.java:485)
        at com.android.server.SystemServer.main(SystemServer.java:325)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:838)
2020-05-06 22:06:04.389 1358-1358/? E/LoadedApk: Unable to instantiate appComponentFactory
    java.lang.ClassNotFoundException: Didn't find class "androidx.core.app.CoreComponentFactory" on path: DexPathList[[],nativeLibraryDirectories=[/data/app/org.luksza.HabitChallenge.dev-Ls9oScDYgr1O8MHW6FSV7A==/lib/arm64, /data/app/org.luksza.HabitChallenge.dev-Ls9oScDYgr1O8MHW6FSV7A==/base.apk!/lib/arm64-v8a, /system/lib64]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        at android.app.LoadedApk.createAppFactory(LoadedApk.java:226)
        at android.app.LoadedApk.updateApplicationInfo(LoadedApk.java:346)
        at android.app.ActivityThread.handleDispatchPackageBroadcast(ActivityThread.java:5534)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1841)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at com.android.server.SystemServer.run(SystemServer.java:485)
        at com.android.server.SystemServer.main(SystemServer.java:325)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:838)

Am I missing some kind of native dependency?

HenriBeck commented 4 years ago

@dluksza Have you already upgraded to androidx? It seems that it can't find a androidx class.

What also seems weird is this line:

2020-05-06 22:06:04.337 3550-3579/? E/neplus.launche: Failed to open APK '/data/app/org.luksza.HabitChallenge.dev-QhBOJOe_r1y8E5XL0WWX1A==/base.apk' I/O error

Could it be that there is a mismatch between your bundle id of the actual app on the device and the bundle id which you have in the return link on the server?

So assuming your bundle id is org.luksza.HabitChallenge.dev, your redirect link on the server should be:

intent://callback?{{queryParams}}#Intent;package=org.luksza.HabitChallenge.dev;scheme=signinwithapple;end
dluksza commented 4 years ago

Yes, I've migrated to androidx a long time ago. It turned out I missed one entry in progurad rules.

I don't really have a server everything runs from firebase. I hoped this would work with firebase-auth.

Also it looks like activity is not set on the plugin. Is it possible that plugin is not fully initialized?

HenriBeck commented 4 years ago

Hmm, I don't think you can get android working without a small server component.

Basically you need a way of redirecting back into the app after you have completed the sign-in process on the Apple website. Only then you can forward the required information to Firebase Auth to my knowledge.

See https://github.com/aboutyou/dart_packages/tree/master/packages/sign_in_with_apple#server

You also added the required activity in the AndroidManifest.xml as described here

dluksza commented 4 years ago

I've added the activity to AndroidManifest.xml

AFAIK sign in with apple on android works like OAtuh2 on the web. This is why server part is needed, am I right?

Also Firebase Auth is doing similar thing for Android support (see https://firebase.google.com/docs/auth/android/apple) my guess was that it should be relatively easy to glue both parts together. But it seems not as easy.

Why do you think this error is returned by native android part of this plugin?

tp commented 4 years ago

Hey @dluksza,

the server part Henri mentioned is only needed to pass the credentials back to the app, it doesn't log the user in or anything like that.

The reason for this is twofold:

So what the HTTPS server-side part does here is forwaring the parameters from Apple to the app via a deeplink.

It might be the case that this whole flow can be simplified/adapted when using Sign in with Apple in conjunction with Firebase and the Firebase provided return URLs. But this would then definitely need a different API as you wouldn't get the raw code back (from the Future this library returns), but rather a logged-in Firebase session.

I think the OP in #62 used the manual integration described here, which should work fine with this library: https://firebase.google.com/docs/auth/android/apple#advanced_handle_the_sign-in_flow_manually

Still you need a tiny server-side part for the redirect described above. Either add that to your existing backend or fork the Glitch.com sample we provide in the README to get a test server for free.

Hope this helps! If you get Firebase Auth working and can provide the steps as a feedback here I will gladly add that to the README as it will for sure help a lot of folks.

HenriBeck commented 4 years ago

I was reading through the Firebase Auth documentation and I believe you have two options here:

  1. Follow the actual Android Guide In this option, you wouldn't need our plugin. Everything should go through the Firebase Auth Flutter plugin. In the Docs the user's code actually never receives the raw credentials, which you would get through our library. Meaning you should be able to initiate an OauthProvider and then authenticate using that.

  2. Follow the iOS Guide also on Android I believe the iOS Guide should actually just also work on Android. So you can set up everything as explained in our README, and then just pass the returned credentials to Firebase as described here. Note that in this case the Return URL that you specify in the Apple Developer Console, can't be the URL from Firebase. This URL needs to point to a server which has this server code running.

dluksza commented 4 years ago

Will leave this as unsupported on Android for now.

I had a small victory with flutter_appauth, namely I was redirected to https://appleid.apple.com, was able to sign in with apple id. But then was redirected to firebase page, not to my app. The registration process was not finished, since no new auth entity was created in Firebase.

As this is first version of my app with auth support. I'll keep it small and add Sing In With Apple in another release.

HenriBeck commented 4 years ago

@dluksza Did you try also just using the iOS way on Android? I guess you have already implemented iOS and the only thing which would be missing for Android would be the server part and changing the Return URL in the Apple Developer Console.

dluksza commented 4 years ago

@HenriBeck yes, probalby I'm only missing the server part and proper configuration in Apple Developer Console. But for now I want to focus on getting out version with accounts and authorization. Later will get back to this.

Thank you all for help and suggestions!

tp commented 4 years ago

But for now I want to focus on getting out version with accounts and authorization. Later will get back to this.

@dluksza So can we close this for now? Whenever you resume work on Sign in with Apple feel free to reach out if there are any issues.

dluksza commented 4 years ago

Sure, we can close it temporary.

neha-madhini commented 4 years ago

Once in a while, when I run or install the android app, on clicking the sign in with apple button, I get google screen, and when I click no thanks button it goes to apple sign in webpage. Again, when I close the app or run, it opens apple sign in webpage on clicking the sign in with apple button.