Giter VIP home page Giter VIP logo

Comments (18)

sageata avatar sageata commented on May 24, 2024 1

So, I used the Firebase Guide for Android for Sign in With Apple and I got to this eventually

package my.package

import android.util.Log
import androidx.annotation.NonNull
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.OAuthProvider
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant


class MainActivity : FlutterActivity() {

    private val channel = "channel.name"
    private val TAG = MainActivity::class.java.simpleName

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, channel).setMethodCallHandler { call, result ->

            if (call.method == "signInWithApple") {
                val auth = FirebaseAuth.getInstance();
                val provider = OAuthProvider.newBuilder("apple.com")
                provider.setScopes(arrayOf("email", "name").toMutableList());
                val pending = auth.pendingAuthResult;

                if (pending != null) {
                    pending.addOnSuccessListener { authResult ->
                        Log.d(TAG, "checkPending:onSuccess:$authResult")

                    }.addOnFailureListener { e ->
                        Log.w(TAG, "checkPending:onFailure", e)
                    }
                } else {
                    Log.d(TAG, "pending: null")
                    auth.startActivityForSignInWithProvider(this, provider.build()).addOnSuccessListener { authResult ->
                        // Sign-in successful!
                        Log.d(TAG, "activitySignIn:onSuccess:${authResult.user}")
                        val user = authResult.user
                    }
                            .addOnFailureListener { e ->
                                Log.w(TAG, "activitySignIn:onFailure", e)
                            }
                }
                result.success("It worked!")
            } else {
                result.notImplemented();
            }
        }

    }
}

I still have some work to do on the above code.

In Flutter I use this to call the function:

if (Platform.isAndroid) {
  final platform = MethodChannel('channel.name');
  platform.invokeMethod('signInWithApple');
}

channel.name can be anything you choose.

I also set a listener on the FirebaseAuth.instance.onAuthStateChanged and if the user is not null then I hide the Login Page.

Also, very important, in Firebase Console, one needs to set up the SHA-1 Fingerprint, otherwise you will get an error complaining about it.

Check this page on how to get the fingerprint

https://developers.google.com/android/guides/client-auth

from dart_packages.

tp avatar tp commented on May 24, 2024

Hey @sageata,

I can't offer a working implementation with Firebase here (as we've never tested it specifically), but there have been various tickets around that here (so I assume quite some people are working on/with it).

If anyone got/gets it working, I would like to add a write-up of that to the docs :)

Do you have any suggestions on what I should do next in order to make it work with the 'https://[appId].firebaseapp.com/__/auth/handler?

What the reference server does on the callback URL is to open a deeplink back to the app, which has 2 jobs:

  • Pass the credential data safely to the app
  • Bring the app back to the foreground, hence having the Android system close the Chrome custom tab shown "above" the app's activity

I don't know how the Firebase handler works or what you can configure there, but if opening a deep link back to your app is possible, that is probably the simplest way.

Apart from that, when using Firebase the login could already be successful when the callback is opened in the Custom tab, so do you get any API feedback for that?

Currently there is no way to close the Chrome Custom Tab from this package, but if that is technically possible and you get some notification that the login was successful, closing the Chrome Custom Tab programmatically might be an alternative to the deep link approach in this case.

from dart_packages.

sageata avatar sageata commented on May 24, 2024

Thank you for the reply @tp

Apart from that, when using Firebase the login could already be successful when the callback is >opened in the Custom tab, so do you get any API feedback for that?

I do not get any Feedback from the API, even after closing the Chrome Tab manually.

I thought that the answer might rest with the AndroidManifest intent, however, I am not sure what I could modify in there to adapt for the Firebase Auth Handler.

I will keep searching for an answer.

from dart_packages.

sageata avatar sageata commented on May 24, 2024

I think I got my answer here:

auth.startActivityForSignInWithProvider(this, provider.build()) .addOnSuccessListener { authResult -> // Sign-in successful! Log.d(TAG, "activitySignIn:onSuccess:${authResult.user}") val user = authResult.user // ... } .addOnFailureListener { e -> Log.w(TAG, "activitySignIn:onFailure", e) }

The current FirebaseAuth package for Flutter does not have this function : startActivityForSignInWithProvider, meaning that the Firebase handler is not designed to return the credential and close app. I think I will have to do the Server bit as well after all 😄

from dart_packages.

HenriBeck avatar HenriBeck commented on May 24, 2024

@sageata I think there are two options here:

  1. Use the Firebase Android Guide. For this option, you wouldn't need our plugin at all; instead, it should be handled all from Firebase Auth package.
    The benefit would that you don't need the mentioned server part because Firebase will take care of it.

  2. Use the iOS Guide also for Android.
    I believe that the iOS guide should also just work on Android with our plugin when you set up the server correctly. That lets our plugin handle all of the authentications and redirecting, and just giving the user data to Firebase once you are out of our flow.

Let us know if you face any issues, and we would be happy to add some docs about the integration because we did already get a few issues about that specific issue

from dart_packages.

sageata avatar sageata commented on May 24, 2024

@HenriBeck Thank you!

I will start with 1. Time to get my hands dirty in some Kotlin code for the first time 😄

from dart_packages.

HenriBeck avatar HenriBeck commented on May 24, 2024

@sageata Then you will most likely need to file a ticket here to get this implemented in Firebase Auth.

from dart_packages.

tp avatar tp commented on May 24, 2024

@sageata If you add this based on top of this library, wouldn't https://firebase.google.com/docs/auth/android/apple#advanced_handle_the_sign-in_flow_manually be the most appropriate?

  1. Generate a nonce
  2. Ask for the token via this plugin
  3. Pass both to Firebase (ideally the API mentioned before is or would be exposed in the Flutter package, so you don't have to have a second native plugin to get the credential to Firebase)

from dart_packages.

sageata avatar sageata commented on May 24, 2024

@tp I didn't know that providing a nonce would make the change the way the plugin works.

I will give it a try.

from dart_packages.

sageata avatar sageata commented on May 24, 2024

@sageata Then you will most likely need to file a ticket here to get this implemented in Firebase Auth.

@HenriBeck Done!

from dart_packages.

tp avatar tp commented on May 24, 2024

For reference: firebase/flutterfire#2691

from dart_packages.

ndhbr avatar ndhbr commented on May 24, 2024

So there is no easy way for the browser to close automatically? Or have I misunderstood something wrong?

from dart_packages.

HenriBeck avatar HenriBeck commented on May 24, 2024

@ndhbr Could you please elaborate? See also #94 which verifies that it is possible to integrate our plugin with Firebase Auth.

from dart_packages.

ndhbr avatar ndhbr commented on May 24, 2024

@HenriBeck

@ndhbr Could you please elaborate? See also #94 which verifies that it is possible to integrate our plugin with Firebase Auth.

I have exactly the same problem as the initial question.

The package works fine under iOS (thanks for that!). And on Android, after login, I am redirected to the RedirectUri as specified. Unfortunately, the browser does not close automatically after that.

So I wanted to ask if there is a simple solution for this or if I should just implement the login for Android manually.

from dart_packages.

tp avatar tp commented on May 24, 2024

So I wanted to ask if there is a simple solution for this or if I should just implement the login for Android manually.

@ndhbr Does your redirect URI call forward further to the app's deeplink? That will cause the Chrome Custom Tab to close (pop) while bringing the Flutter activity back to the foreground.

from dart_packages.

ndhbr avatar ndhbr commented on May 24, 2024

@ndhbr Does your redirect URI call forward further to the app's deeplink? That will cause the Chrome Custom Tab to close (pop) while bringing the Flutter activity back to the foreground.

Unfortunately not. If I understand this correctly, the server should append the parameters, right?

Maybe I should have said that I use Firebase as well. So I have as callback URL only https://[appId].firebaseapp.com/__/auth/handler
without additional parameters.

With Firebase you cannot configure this either. If I close the tab manually nothing happens, so the login was not successful.

firebase

I have implemented the Google Login with another package. Since Apple doesn't have a native Google Login either, it is done via the browser, like the Apple Login on Android, on iOS. But after the login the browser closes and I get the credential in the code.

Unfortunately I don't get the credential here when I close the browser manually because it throws the exception SignInWithAppleAuthorizationException - The user closed the Custom Tab.

from dart_packages.

HenriBeck avatar HenriBeck commented on May 24, 2024

@ndhbr You don't want to use the Firebase Auth callback URL when you integrate it with this package.

For our package to work, you will need this small server component as described in the README. Then we will link back to your app and return you the credentials of the user.
https://github.com/aboutyou/dart_packages/tree/master/packages/sign_in_with_apple#server

Then you can give those credentials to firebase using:

final credential = OAuthProvider(providerId: 'apple.com').getCredential(
    idToken: appleIdCredential.identityToken,
    accessToken: appleIdCredential.authorizationCode,
);

from dart_packages.

ndhbr avatar ndhbr commented on May 24, 2024

For our package to work, you will need this small server component as described in the README. Then we will link back to your app and return you the credentials of the user.
https://github.com/aboutyou/dart_packages/tree/master/packages/sign_in_with_apple#server

@HenriBeck Thanks for the help. I'm gonna try this.

Then you can give those credentials to firebase using:

final credential = OAuthProvider(providerId: 'apple.com').getCredential(
    idToken: appleIdCredential.identityToken,
    accessToken: appleIdCredential.authorizationCode,
);

I have already implemented this, thank you!

from dart_packages.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.