capawesome-team / capacitor-firebase

⚑️ Firebase plugins for Capacitor. Supports Android, iOS and the Web.
https://capawesome.io/plugins/firebase/
Apache License 2.0
392 stars 101 forks source link

feat(authentication): support OpenID Connect #275

Closed LisaScheers closed 5 months ago

LisaScheers commented 1 year ago

Is your feature request related to a problem? Please describe:

firebase now supports custom OpenID and SAML providers

Describe the solution you'd like:

add a method like signInWithCustomProvider

Describe alternatives you've considered:

NA

Additional context:

Android implementation IOS implementation Web Implementation

djabif commented 6 months ago

Hi @robingenz, thanks for this amazing plugin! Just wanted to check if you have plans to add this? My team is considering using an OIDC provider and we also use anonymous login so we need to be able to link the profiles. Thanks 😊

robingenz commented 6 months ago

It seems like this should be easy to implement. I will add it to my todo list.

s-frei commented 5 months ago

Hi, first of all, thank you for your work on this project @robingenz! We're starting to depend on this feature to provide unique user IDs accross several applications from anohter identity provider. We are still evaluating if capacitor is the right way for our project, but we won't accomplish to make it work without the custom OIDC provider authentication option. Did you plan to provide this feature anytime soon? We're also willing to start sponsoring this project!

robingenz commented 5 months ago

@s-frei There are various ways in which you can prioritize this issue, see After creating an issue. And yes, one of them is sponsoring. Feel free to send me an e-mail to support@capawesome.io if you’re interested.

seletz commented 5 months ago

@robingenz just wrote a mail to get this going forward. @s-frei is a collegue of mine.

seletz commented 5 months ago

@robingenz just wrote a mail to get this going forward. @s-frei is a collegue of mine.

So I've just put in some $$ to sponsor development of this issue. πŸ‘

robingenz commented 5 months ago

The first dev version is now available:

npm i @capacitor-firebase/authentication@6.0.0-dev.1cf9434.1715181187

There are three new methods:

import { FirebaseAuthentication } from '@capacitor-firebase/authentication';

// See https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseAuth#getPendingAuthResult()
const getPendingAuthResult = async () => {
  const result = await FirebaseAuthentication.getPendingAuthResult();
  return result.user;
};

const signInWithOpenIdConnect = async () => {
  const result = await FirebaseAuthentication.signInWithOpenIdConnect({
    providerId: 'oidc.example.com',
  });
  return result.user;
};

const linkWithOpenIdConnect = async () => {
  const result = await FirebaseAuthentication.linkWithOpenIdConnect({
    providerId: 'oidc.example.com',
  });
  return result.user;
};

I would love to get some feedback.

s-frei commented 5 months ago

Hi @robingenz that was quick, thank you! I will test it and provide feedback on monday πŸ™‚

s-frei commented 5 months ago

As far as I can tell signInWithOpenIdConnect works like a charm πŸ₯³ , at least using Keycloak as OIDC provider. I didn't had to use getPendingAuthResult yet, since there always was an auth result present, or am I missing something?

The linkWithOpenIdConnect I just have to use if I got multiple auth providers and I want to link one authentication to another?

s-frei commented 5 months ago

Well, on iOS the promise returns an error:

{"code":"UNIMPLEMENTED"}

and on Android:

"FirebaseAuthentication.signInWithOpenIdConnect()" is not implemented on android

even tho I see following when launching the apps:

[info] Found 8 Capacitor plugins for ios:
       @capacitor-firebase/authentication@6.0.0-dev.1cf9434.1715181187

[info] Found 8 Capacitor plugins for android:
       @capacitor-firebase/authentication@6.0.0-dev.1cf9434.1715181187

Seems like a caching problem, but I'm not managing to fix it...

EDIT: The code you added is present in the src-capacitor/node_modules/@capacitor-firebase/authentication/ directory.

robingenz commented 5 months ago

@s-frei Thank you for your feedback!

I didn't had to use getPendingAuthResult yet, since there always was an auth result present, or am I missing something?

You should call getPendingAuthResult() directly at app start to check if your app was killed by the OS during the auth process.

The linkWithOpenIdConnect I just have to use if I got multiple auth providers and I want to link one authentication to another?

Exactly.

Well, on iOS the promise returns an error:

Sorry, this was my fault. I just published a new version:

npm i @capacitor-firebase/authentication@6.0.0-dev.80d9693.1715591909

Make sure to run npx cap sync after the installation.

and on Android:

It should already work on Android. πŸ€”

s-frei commented 5 months ago

Now it works on iOS! The issue on Adnroid is unfortunately still the same. I completely rebuilt it an wiped the device data. It seems like the correct code is displayed in Android Studio and I also can find the signInWithOpenIdConnect() method.

robingenz commented 5 months ago

@s-frei I will take another look at Android later.

robingenz commented 5 months ago

@s-frei Okay, i fixed one last issue. Now it should also work on Android:

npm i @capacitor-firebase/authentication@6.0.0-dev.19f3631.1715622087
s-frei commented 5 months ago

@robingenz perfect, thank you! Will test it tomorrow.

s-frei commented 5 months ago

@robingenz ok, Android seems to work now! The application gets killed in the background, at least when the browser isn't set up yet. But I guess that is the point where getPendingAuthResult comes handy πŸ™‚

robingenz commented 5 months ago

@s-frei Exactly! Thanks for the update.

s-frei commented 4 months ago

@robingenz just encountered another error using the getPendingAuthResult on Android.

When there is no pending auth result retrieved at https://github.com/capawesome-team/capacitor-firebase/blob/e4fee1e03c07b98a354193654627a0779d115aa4/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/OAuthProviderHandler.java#L29 the passed authResult is null and produces a NullPointerException here https://github.com/capawesome-team/capacitor-firebase/blob/main/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java#L747

Attempt to invoke interface method 'com.google.firebase.auth.FirebaseUser com.google.firebase.auth.AuthResult.getUser()' on a null object reference
    java.lang.NullPointerException: Attempt to invoke interface method 'com.google.firebase.auth.FirebaseUser com.google.firebase.auth.AuthResult.getUser()' on a null object reference
        at io.capawesome.capacitorjs.plugins.firebase.authentication.FirebaseAuthentication.handleSuccessfulSignIn(FirebaseAuthentication.java:727)
        at io.capawesome.capacitorjs.plugins.firebase.authentication.handlers.OAuthProviderHandler.getPendingAuthResult(OAuthProviderHandler.java:29)
        at io.capawesome.capacitorjs.plugins.firebase.authentication.FirebaseAuthentication.getPendingAuthResult(FirebaseAuthentication.java:186)
        at io.capawesome.capacitorjs.plugins.firebase.authentication.FirebaseAuthenticationPlugin.getPendingAuthResult(FirebaseAuthenticationPlugin.java:250)
robingenz commented 4 months ago

@s-frei Thank you for reporting this. I've just published a dev version with a fix:

npm i @capacitor-firebase/authentication@6.0.0-dev.78b3388.1717571627
s-frei commented 4 months ago

@robingenz tested it and no more exceptions πŸ‘πŸ½ Thank you!

Unrelated: Found another nullability issue in the storage module. This line failes when no customMetadata is provided at https://github.com/capawesome-team/capacitor-firebase/blob/e4fee1e03c07b98a354193654627a0779d115aa4/packages/storage/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/storage/FirebaseStorageHelper.java#L22 (throwing a JSONException https://stleary.github.io/JSON-java/org/json/JSONObject.html#getJSONObject-java.lang.String-). Was about to open a bug issue for that, but the effort (due to requirements) to report such a small bug seemed way to much for me. Edit: Well, I just noticed that there is another layer by capacitor for JSONObject and this could be just fixed using https://github.com/ionic-team/capacitor/blob/b32b5b17ed14bd43c846b3fcb930bfd88e245e40/android/capacitor/src/main/java/com/getcapacitor/JSObject.java#L90. I for sure could provide that, but have nothing to reference...

robingenz commented 4 months ago

@s-frei Thank you. I have also just fixed this and released a dev version:

npm i @capacitor-firebase/storage@6.0.0-dev.688792b.1717573789

Was about to open a bug issue for that, but the effort (due to requirements) to report such a small bug seemed way to much for me.

In such an obvious case, you can simply skip the minimal, reproducible example etc.. However, I need this information for the majority of issues.