Comments (65)
Hello. I was checking out your project and it seems to work with firebase auth. This is my example code for someone who needs this for future reference
Future<FirebaseUser> signInWithApple() async {
var redirectURL = "https://SERVER_AS_PER_THE_DOCS.glitch.me/callbacks/sign_in_with_apple";
var clientID = "AS_PER_THE_DOCS";
final appleIdCredential = await SignInWithApple.getAppleIDCredential(
scopes: [
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
webAuthenticationOptions: WebAuthenticationOptions(
clientId: clientID,
redirectUri: Uri.parse(
redirectURL)));
final oAuthProvider = OAuthProvider(providerId: 'apple.com');
final credential = oAuthProvider.getCredential(
idToken: appleIdCredential.identityToken,
accessToken: appleIdCredential.authorizationCode,
);
final authResult =
await SignInUtil.firebaseAuth.signInWithCredential(credential);
return authResult.user;
}
As a note I got it working with iOS and Android through firebase.
from dart_packages.
For anyone using Firebase and not wanting to setup a glitch project to process the callback, you can implement the same functionality of the glitch project using Firebase hosting and cloud functions as follows (using typescript):
in index.ts
import * as functions from 'firebase-functions';
import express = require('express');
import { URLSearchParams } from 'url';
const app = express();
app.use(express.urlencoded({ extended: false }));
process.env.ANDROID_PACKAGE_IDENTIFIER = '<your_android_app_package_id>';
app.post("*/app/callbacks/sign_in_with_apple", (request, response) => {
const redirect = `intent://callback?${new URLSearchParams(
request.body
).toString()}#Intent;package=${process.env.ANDROID_PACKAGE_IDENTIFIER
};scheme=signinwithapple;end`;
console.log(`Redirecting to ${redirect}`);
response.redirect(307, redirect);
});
exports.app = functions.https.onRequest(app);
in your firebase.json, in hosting section, setup url rewrite to call the function:
...
"hosting": {
"public": "public",
"rewrites": [
{
"source": "/app/**",
"function": "app"
}
you can then use the following as a callback from apple-sign-in:
https://[firebase project id].web.app/app/callbacks/sign_in_with_apple
you can test with:
curl -X POST -H "Content-Type:application/json" 'https://[firebase project id].web.app/app/callbacks/sign_in_with_apple' -d '{"test":"something"}'
if all is working you should see the following test results:
Temporary Redirect. Redirecting to intent://callback?test=something#Intent;package=[your_android_app_package_id];scheme=signinwithapple;end
When the callback is called from apple, and with your intent properly setup in your AndroidManifest.xml according to package docs: https://pub.dev/packages/sign_in_with_apple, your app's call to SignInWithApple.getAppleIDCredential will get a AuthorizationCredentialAppleID returned with token and auth code that you can use to create a Firebase Auth Credential and sign-in:
final appleUser = await SignInWithApple.getAppleIDCredential(
scopes: [AppleIDAuthorizationScopes.email, AppleIDAuthorizationScopes.fullName],
webAuthenticationOptions: WebAuthenticationOptions(
clientId: '[your Service ID from Apple Dev setup]',
redirectUri: Uri.parse('https://[firebase_project_id].web.app/app/callbacks/sign_in_with_apple')),
);
final oAuthProvider = firebase_auth.OAuthProvider('apple.com');
final credential = oAuthProvider.credential(
accessToken: appleUser.authorizationCode,
idToken: appleUser.identityToken);
_firebaseAuth.signInWithCredential(credential);
*Be sure to add the callback URL and domain in your Apple Dev account within the Web Authentication Configuration in your Service ID Sign-in-with-Apple config setup).
from dart_packages.
I'm using Firebase Auth not a custom server.
Hey,
the above is only needed when using a custom server, which is meant to mean that you should copy over the POST body (that Apple posts to your server) to that query parameter.
For Firebase we don't have documentation, but anecdotally we know that it works 😉
It depends on the type of integration you want to do, but maybe one of the earlier issues around this helps get you started: https://github.com/aboutyou/dart_packages/issues?q=is%3Aissue+firebase
We'd definitely be grateful for a write-up on how to integrate this with Firebase.
I will close this for now. But feel free to reopen if we can help you any further.
from dart_packages.
@HenriBeck Thanks for your answer. What is blocking to use Firebase Hosting auth handler?
from dart_packages.
For anyone using Firebase and not wanting to setup a glitch project to process the callback, you can implement the same functionality of the glitch project using Firebase hosting and cloud functions as follows (using typescript):
in index.ts
import * as functions from 'firebase-functions'; import express = require('express'); import { URLSearchParams } from 'url'; const app = express(); app.use(express.urlencoded({ extended: false })); process.env.ANDROID_PACKAGE_IDENTIFIER = '<your_android_app_package_id>'; app.post("*/app/callbacks/sign_in_with_apple", (request, response) => { const redirect = `intent://callback?${new URLSearchParams( request.body ).toString()}#Intent;package=${process.env.ANDROID_PACKAGE_IDENTIFIER };scheme=signinwithapple;end`; console.log(`Redirecting to ${redirect}`); response.redirect(307, redirect); }); exports.app = functions.https.onRequest(app);in your firebase.json, in hosting section, setup url rewrite to call the function:
... "hosting": { "public": "public", "rewrites": [ { "source": "/app/**", "function": "app" }you can then use the following as a callback from apple-sign-in: https://[firebase project id].web.app/app/callbacks/sign_in_with_apple
you can test with:
curl -X POST -H "Content-Type:application/json" 'https://[firebase project id].web.app/app/callbacks/sign_in_with_apple' -d '{"test":"something"}'if all is working you should see the following test results:
Temporary Redirect. Redirecting to intent://callback?test=something#Intent;package=[your_android_app_package_id];scheme=signinwithapple;end
When the callback is called from apple, and with your intent properly setup in your AndroidManifest.xml according to package docs: https://pub.dev/packages/sign_in_with_apple, your app's call to SignInWithApple.getAppleIDCredential will get a AuthorizationCredentialAppleID returned with token and auth code that you can use to create a Firebase Auth Credential and sign-in:
final appleUser = await SignInWithApple.getAppleIDCredential( scopes: [AppleIDAuthorizationScopes.email, AppleIDAuthorizationScopes.fullName], webAuthenticationOptions: WebAuthenticationOptions( clientId: '[your Service ID from Apple Dev setup]', redirectUri: Uri.parse('https://[firebase_project_id].web.app/app/callbacks/sign_in_with_apple')), ); final oAuthProvider = firebase_auth.OAuthProvider('apple.com'); final credential = oAuthProvider.credential( accessToken: appleUser.authorizationCode, idToken: appleUser.identityToken); _firebaseAuth.signInWithCredential(credential);*Be sure to add the callback URL and domain in your Apple Dev account within the Web Authentication Configuration in your Service ID Sign-in-with-Apple config setup).
This one works, thanks!!
Been trying to find a solution everywhere.
Needed to do a couple of changes though.
Need to "Set up Firebase Hosting" first, selecting TypeScript as a language. (go to Firebase -> Hosting, and follow instructions)
firebase login
firebase init firestore
firebase init functions (select Typescript)
When the files are created using the firebase command, copy the code above to the src/index.ts file.
Then run this command to deploy the function:
firebase deploy --only functions
This also created an http Function. (Firebase -> Functions).
Also in my case you the root was app/ so removed the extra app as well, so ended up like this:
app.post("*/callbacks/sign_in_with_apple", (request, response) => {
Run npm run serve while in the functions folder to test it locally:
functions$ npm run serve
Extra steps:
Also added this URL (https://us-central1-{YOUR-FIREBASE-PROJECT}.cloudfunctions.net/app/callbacks/sign_in_with_apple) on my Service ID Identifier from the Apple Developer website.
This was also the redirect URL that I was using in my project.
from dart_packages.
There is no need for a return url on iOS. Just follow the detailed guide in the readme, skip the android and Glitch server part, and it should work.
from dart_packages.
Thanks, @mpiparo that works. Maybe include these steps along with the steps on glitch? With how common it is to use Firebase with Flutter this would make sense. I am still hoping the Flutterfire team is going to make apple auth on android work out of the box, though.
from dart_packages.
@HenriBeck I've setup the server now as per the docs, what's the next step?
intent://callback?${PARAMETERS FROM CALLBACK BODY}#Intent;package=YOUR.PACKAGE.IDENTIFIER;scheme=signinwithapple;end
What do I put in the ${PARAMATERS FROM CALLBACK BODY} part?
from dart_packages.
Hello @DavidCorrado, all,
Future<FirebaseUser> signInWithApple() async { var redirectURL = "https://SERVER_AS_PER_THE_DOCS.glitch.me/callbacks/sign_in_with_apple"; var clientID = "AS_PER_THE_DOCS"; final appleIdCredential = await SignInWithApple.getAppleIDCredential( scopes: [ AppleIDAuthorizationScopes.email, AppleIDAuthorizationScopes.fullName, ], webAuthenticationOptions: WebAuthenticationOptions( clientId: clientID, redirectUri: Uri.parse( redirectURL))); final oAuthProvider = OAuthProvider(providerId: 'apple.com'); final credential = oAuthProvider.getCredential( idToken: appleIdCredential.identityToken, accessToken: appleIdCredential.authorizationCode, ); final authResult = await SignInUtil.firebaseAuth.signInWithCredential(credential); return authResult.user; }As a note I got it working with iOS and Android through firebase.
I copied the code as is and added it to sign_in_with_apple/example/lib/main.dart.
I set the redirectURL
and clientID
to the correct values.
I verified that a simple CURL request returns correctly:
$ curl -X POST https://PROJECT.glitch.me/callbacks/sign_in_with_apple
returns with:
< HTTP/2 307
< date: Sun, 18 Oct 2020 18:36:16 GMT
< content-type: text/plain; charset=utf-8
< content-length: 103
< location: intent://callback?#Intent;package=BUNDLE_ID;scheme=signinwithapple;end
< x-powered-by: Express
< vary: Accept
I also verified the return URL is correctly configured in the service identifier on Apple's end.
When I invoke signInWithApple()
, from Android, I get to the Apple login screen (https://appleid.apple.com/auth..), I am successfully authenticated and asked if I'd like to continue. Upon clicking on Continue
(on the Apple page), I briefly see the Android logo and am then navigated to a blank screen with a throbber.
I put a debug print right after the SignInWithApple.getAppleIDCredential()
call. I am not getting there.
In the console, I see:
D/SurfaceView(20638): onWindowVisibilityChanged(4) false io.flutter.embedding.android.FlutterSurfaceView{7955dfd V.E...... ........ 0,0-720,1436} of ViewRootImpl@981fa54[MainActivity]
D/ViewRootImpl@981fa54MainActivity: Relayout returned: old=[0,0][720,1520] new=[0,0][720,1520] result=0x1 surface={false 0} changed=false
D/ViewRootImpl@981fa54MainActivity: stopped(false) old=true
D/SurfaceView(20638): windowStopped(false) false io.flutter.embedding.android.FlutterSurfaceView{7955dfd V.E...... ........ 0,0-720,1436} of ViewRootImpl@981fa54[MainActivity]
D/ViewRootImpl@981fa54MainActivity: stopped(false) old=false
Until I finally give up and get:
E/flutter (20638): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: SignInWithAppleAuthorizationError(AuthorizationErrorCode.canceled, The user closed the Custom Tab)
Any help would be most appreciated.
Cheers,
from dart_packages.
This is my manifest (same as yours)
manifest
<!-- Apple sign in -->
<!-- see https://pub.dev/packages/sign_in_with_apple#-readme-tab -->
<activity android:name="com.aboutyou.dart_packages.sign_in_with_apple.SignInWithAppleCallback"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="signinwithapple" />
<data android:path="callback" />
</intent-filter>
</activity>
And the server side code to call back to Android, which is mostly the same too.
Server code
// The callback route used for Android, which will send the callback parameters from Apple into the Android app.
// This is done using a deeplink, which will cause the Chrome Custom Tab to be dismissed and providing the parameters from Apple back to the app.
app.post("/callbacks/sign_in_with_apple", (request, response) => {
console.log(`Request to callbacks`);
const redirect = `intent://callback?${new URLSearchParams(
request.body
).toString()}#Intent;package=${functions.config().apple.android_package_identifier};scheme=signinwithapple;end`;
console.log(`Response ${response}`);
console.log(`Redirecting to ${redirect}`);
response.redirect(307, redirect);
});
from dart_packages.
I made a dead simple python script for AWS Lambda (+ API Gateway) that does the redirect magic in case it helps anyone:
import json
import base64
def lambda_handler(event, context):
print(event)
redirectActivityIdentifier = 'com.example.app'
redirectData = base64.b64decode(event['body']).decode('ascii')
redirect = f"intent://callback?{redirectData}#Intent;package={redirectActivityIdentifier};scheme=signinwithapple;end"
print(f"redirecting to {redirect}")
return {
'statusCode': 307,
'headers': {'Location': redirect},
'body': json.dumps({})
}
Got Apple login through Firebase working on Android (can't seem to get Apple login to work on my iOS simulator funnily enough because of https://developer.apple.com/forums/thread/651533?page=10).
from dart_packages.
Hi @tstrg,
May I ask what's your solution to your error?
Because my error is the same as yours. I'm able to authenticate but when I clicked continue it redirects to my app in playstore and when I open it the error shows:
SignInWithAppleAuthorizationError(AuthorizationErrorCode.canceled, The user closed the Custom Tab)
from dart_packages.
The flow should be similar, I expect to use SignInWithApple.getAppleIDCredential
to get a AuthorizationCredentialAppleID
containing a crucial IdToken
which I then supply to Firebase.
FirebaseAuth.instance.signInWithCredential(
PlatformOAuthCredential(
providerId: 'apple.com',
idToken: credential.identityToken,
rawNonce: nonce,
),
);
Inspired by this snippet.
https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_auth/firebase_auth_platform_interface/lib/src/types.dart#L162
On that note, should the AuthorizationCredentialAppleID
also contain an accessToken?
from dart_packages.
@britannio I think the accessToken
is named authorizationCode
in sign in with apple
from dart_packages.
@britannio I think the
accessToken
is namedauthorizationCode
in sign in with apple
ah, thanks!
from dart_packages.
@tp Can we keep this open until a complete solution is found? Firebase provides a call-back URL but I think it's for web purposes and besides that, only the url scheme we define will open the app.
from dart_packages.
@britannio Sure, seems like this is going somewhere :) Then let's use this to get a codesample documenting the flow with Firebase.
from dart_packages.
@britannio but what's the hold up now? I think the integration with firebase auth should just work as described in the Firebase Auth iOS Apple docs (also on Android it should).
You get the credentials from this plugin and then just give them to firebase so it can create the user in the firebase backend.
That should also work for Android, you just need this small server part to redirect back into the app on android.
from dart_packages.
@HenriBeck Not knowing what to provide to the redirectUri
of WebAuthenticationOptions
.
It's of this form:
intent://callback?${PARAMETERS FROM CALLBACK BODY}#Intent;package=YOUR.PACKAGE.IDENTIFIER;scheme=signinwithapple;end
but I'm unaware of what I should replace ${PARAMETERS FROM CALLBACK BODY}
with
from dart_packages.
@britannio The redirectUri
shouldn't be intent://callback?${PARAMETERS FROM CALLBACK BODY}#Intent;package=YOUR.PACKAGE.IDENTIFIER;scheme=signinwithapple;end
.
It should be the URL to small server that is needed for android, in the example in the readme it is https://flutter-sign-in-with-apple-example.glitch.me/callbacks/sign_in_with_apple
.
This intent://
URL is defined on the server here in line 25 of server.js
from dart_packages.
@HenriBeck So is the redirectUri
expected to accept requests from Apple's servers and redirect them to the intent://
url where they're intercepted by the app?
from dart_packages.
yes exactly, so when you call getAppleIDCredential
we redirect to the apple website and send along the redirectUri
.
Once the user has finished authenticating, Apple will redirect to the redirectUri
with a POST request. Note that the redirectUri
needs to be an https
URI, that's why we can't simply directly link into the app.
Then on the server part, the user data is received, and you are being redirected to the intent://
URI which in turn is intercepted by the app. The app then returns the data which was in the intent://
URI
from dart_packages.
@DavidCorrado That is great to hear. I will mark this ticket then as documentation
so we can write some document where the full integration is explained.
from dart_packages.
Hello. I was checking out your project and it seems to work with firebase auth. This is my example code for someone who needs this for future reference
Future<FirebaseUser> signInWithApple() async { var redirectURL = "https://SERVER_AS_PER_THE_DOCS.glitch.me/callbacks/sign_in_with_apple"; var clientID = "AS_PER_THE_DOCS"; final appleIdCredential = await SignInWithApple.getAppleIDCredential( scopes: [ AppleIDAuthorizationScopes.email, AppleIDAuthorizationScopes.fullName, ], webAuthenticationOptions: WebAuthenticationOptions( clientId: clientID, redirectUri: Uri.parse( redirectURL))); final oAuthProvider = OAuthProvider(providerId: 'apple.com'); final credential = oAuthProvider.getCredential( idToken: appleIdCredential.identityToken, accessToken: appleIdCredential.authorizationCode, ); final authResult = await SignInUtil.firebaseAuth.signInWithCredential(credential); return authResult.user; }As a note I got it working with iOS and Android through firebase.
Hello, could you please specify how you did manage to authenticate via Firebase on Android?
The issue here is that the redirect URI provided by Firebase apparently cannot be extended with the "intent://..." part required by Android; however, without the "intent://..." part, the authentication tab remains open on Android, thus stalling the authentication flow.
Note that on iOS, where no "intent://..." is required, authentication via Firebase appears to work perfectly every time.
Thank you,
Dario
from dart_packages.
@adario you will need this small server as described in the README here: https://github.com/aboutyou/dart_packages/tree/master/packages/sign_in_with_apple#server
When you then get back the credentials from our plugin, you can create the user the same way you already do on iOS.
from dart_packages.
@adario you will need this small server as described in the README here: https://github.com/aboutyou/dart_packages/tree/master/packages/sign_in_with_apple#server
When you then get back the credentials from our plugin, you can create the user the same way you already do on iOS.
@HenriBeck I've created the server as described in the README, and I'm passing it in 'redirectUri' — the authentication tab is now dismissed as expected, but authentication fails on Android with this error:
AppleSignIn: Error = PlatformException(ERROR_INVALID_CREDENTIAL, The supplied auth credential is malformed or has expired. [ The audience in ID Token [..*] does not match the expected audience. ], null)
(The token above has been redacted.)
from dart_packages.
@adario I think you put in the wrong identifier when setting up Sign in with Apple on the Firebase website.
My guess is that you put in your normal bundle identifier into Firebase Auth and not the correct Service ID you have configured on Apple's side. That's why you get a mismatch.
For more information see this issue: #94
from dart_packages.
@HenriBeck Unfortunately that's not the problem, otherwise I wouldn't have written here...
Firebase Auth is configured with the service ID in the console, not the bundle ID — I'm only using the bundle ID on iOS, never on Android.
from dart_packages.
@HenriBeck After doing a flutter clean
, and without touching anything, it's now working on Android too — I guess a Hot Reload was not enough... ;-)
Any plans to remove the need for the extra server on Android?
Thanks,
Dario
from dart_packages.
@adario There are no plans to remove the extra server as there is no other way to launch the App on Android without it.
Seems weird that a hot reload fixed that particular issue, but it's always required to do a full restart for packages that have native Android/iOS code, which our package has.
from dart_packages.
@HenriBeck Actually, I wrote that a hot reload was not enough — I had to do a flutter clean
to get it working.
Thanks for the clarification about Android.
from dart_packages.
I'm using Firebase Auth not a custom server.
Hey,
the above is only needed when using a custom server, which is meant to mean that you should copy over the POST body (that Apple posts to your server) to that query parameter.
For Firebase we don't have documentation, but anecdotally we know that it works 😉
It depends on the type of integration you want to do, but maybe one of the earlier issues around this helps get you started: https://github.com/aboutyou/dart_packages/issues?q=is%3Aissue+firebase
We'd definitely be grateful for a write-up on how to integrate this with Firebase.
I will close this for now. But feel free to reopen if we can help you any further.
Can you please elaborate a bit about this, where your say: POST body (that Apple posts to your server) to that query parameter
Can you give me some links or some guidance so I can get this package working on Android with firebase.
Thank you
from dart_packages.
POST body (that Apple posts to your server) to that query parameter
@gerryau The above text refers to the custom server which is needed for Android support as described in the here in the readme.
You will then need to provide the URL to your own server in getAppleIDCredential
via the webAuthenticationOptions
from dart_packages.
@HenriBeck Okay thanks,
Do I need to use glitch for this or can I use firebase hosting? Are there any guides for doing this with fire base
from dart_packages.
Do I need to use glitch for this or can I use firebase hosting? Are there any guides for doing this with firebase
You don't have to use glitch of course, in the end, it's just a plain HTTP server. But you can't use the Firebase Auth server.
intent://callback?${PARAMETERS FROM CALLBACK BODY}#Intent;package=YOUR.PACKAGE.IDENTIFIER;scheme=signinwithapple;end
This is part of the server code you can see on the glitch example.
from dart_packages.
On Android I'm now using the Android Firebase SDK to handle this
Plugin: https://github.com/britannio/android_firebase_siwa
I just followed https://firebase.google.com/docs/auth/android/apple#handle_the_sign-in_flow_with_the_firebase_sdk
I'd rather use the alternative approach the docs describe and potentially show a web view instead of leaving the app but step 2 requires initiating the auth process yourself and I don't think this package can do that and redirect back into the app to access the tokens without a http server.
from dart_packages.
@britannio so what's the question/issue? For our package, you will always need this HTTP server to redirect back into the app again.
from dart_packages.
Hi guys,
has anyone tried using Sign In with Apple with Firebase anonymous accounts? I'm getting an error saying Duplicate credential received. Please try again with a new credential.
when trying to link an anonymous account with Apple credentials I used to sign in to my app before. I then need to regenerate credentials in order for this to work. The problem is that the Apple sign in flow will need to be shown again. Here's my code:
Future<AuthCredential> _generateAppleCredential(
{String baseUrl, String clientId}) async {
final redirectURL = "https://$baseUrl/signInWithApple";
final rawNonce = AuthenticationHelper.randomNonceString();
final appleIdCredential = await SignInWithApple.getAppleIDCredential(
scopes: [AppleIDAuthorizationScopes.email],
nonce: AuthenticationHelper.toSha256(rawNonce),
webAuthenticationOptions: WebAuthenticationOptions(
clientId: clientId, redirectUri: Uri.parse(redirectURL)),
);
final oAuthProvider = OAuthProvider(providerId: "apple.com");
return oAuthProvider.getCredential(
idToken: appleIdCredential.identityToken,
accessToken: appleIdCredential.authorizationCode,
rawNonce: rawNonce,
);
}
@override
Future<User> signInWithApple({String baseUrl, String clientId}) async {
final currentUser = await _auth.currentUser();
if (currentUser == null) return null;
final credential = await _generateAppleCredential(
baseUrl: baseUrl,
clientId: clientId,
);
try {
final result = await currentUser.linkWithCredential(credential);
final user = result.user?.user;
_streamController.sink.add(user);
return user;
} on PlatformException catch (e) {
if (e.code == "ERROR_CREDENTIAL_ALREADY_IN_USE") {
final result = await _auth.signInWithCredential(credential); // throws an error here
return result.user?.user;
} else {
throw UserError.Unknown;
}
}
}
The way to accomplish this on iOS is that the error returns updated credentials under AuthErrorUserInfoUpdatedCredentialKey
which then can be used to sign in without reauthenticating with Apple. Unfortunately, there is nothing similar in Flutter in PlatformException under details (it's null).
from dart_packages.
In the server.js, in this line-
intent://callback?${PARAMETERS FROM CALLBACK BODY}#Intent;package=YOUR.PACKAGE.IDENTIFIER;scheme=signinwithapple;end
need to change only the package?
or if {PARAMETERS FROM CALLBACK BODY} also need to be changed, could you tell me what to be added here?
from dart_packages.
@neha-madhini you only need to change your package identifier
from dart_packages.
For anyone else who was getting the following error:
supplied auth credential is malformed, has expired or is not currently supported
Firebase have changed how they do the OAuth authentication with the latest Flutter libraries. The following code contains both the old and new way of creating the credential:
// This is the section that decodes the session response to retrieve the access and id tokens
// We can use this to generate an OAuthCredential that can be used with FireBase.
Map<String, dynamic> appleValidationReponse = jsonDecode(session.body);
// This no longer works with the latest Firebase Flutter libraries
// OAuthCredential authCredential = OAuthCredential(
// providerId: "apple.com",
// signInMethod: "",
// idToken: appleValidationReponse['idToken'],
// accessToken: appleValidationReponse['accessToken'],
// rawNonce: nonce.toString(),
// );
final oAuthProvider = OAuthProvider('apple.com');
final providerCredential = oAuthProvider.credential(
idToken: appleValidationReponse['idToken'],
accessToken: appleValidationReponse['accessToken'],
rawNonce: nonce.toString(),
);
// Authenticate with firebase
UserCredential authResult = await _auth.signInWithCredential(providerCredential);
Full working code example.
from dart_packages.
Hello. I was checking out your project and it seems to work with firebase auth. This is my example code for someone who needs this for future reference
Future<FirebaseUser> signInWithApple() async { var redirectURL = "https://SERVER_AS_PER_THE_DOCS.glitch.me/callbacks/sign_in_with_apple"; var clientID = "AS_PER_THE_DOCS"; final appleIdCredential = await SignInWithApple.getAppleIDCredential( scopes: [ AppleIDAuthorizationScopes.email, AppleIDAuthorizationScopes.fullName, ], webAuthenticationOptions: WebAuthenticationOptions( clientId: clientID, redirectUri: Uri.parse( redirectURL))); final oAuthProvider = OAuthProvider(providerId: 'apple.com'); final credential = oAuthProvider.getCredential( idToken: appleIdCredential.identityToken, accessToken: appleIdCredential.authorizationCode, ); final authResult = await SignInUtil.firebaseAuth.signInWithCredential(credential); return authResult.user; }As a note I got it working with iOS and Android through firebase.
Is it valid for the newest version of firebase plugin?
I just need the functionality for ios.
Isn't there any way to use it without Glitch?
from dart_packages.
@MeshkaniMohammad for iOS you don't need the Glitch server, it is only required for the Android integration.
from dart_packages.
@HenriBeck So I just need to register my call back URL
as redirectUrl
and register it as a returnUrl
in this link?
from dart_packages.
Hello. I was checking out your project and it seems to work with firebase auth. This is my example code for someone who needs this for future reference
Future<FirebaseUser> signInWithApple() async { var redirectURL = "https://SERVER_AS_PER_THE_DOCS.glitch.me/callbacks/sign_in_with_apple"; var clientID = "AS_PER_THE_DOCS"; final appleIdCredential = await SignInWithApple.getAppleIDCredential( scopes: [ AppleIDAuthorizationScopes.email, AppleIDAuthorizationScopes.fullName, ], webAuthenticationOptions: WebAuthenticationOptions( clientId: clientID, redirectUri: Uri.parse( redirectURL))); final oAuthProvider = OAuthProvider(providerId: 'apple.com'); final credential = oAuthProvider.getCredential( idToken: appleIdCredential.identityToken, accessToken: appleIdCredential.authorizationCode, ); final authResult = await SignInUtil.firebaseAuth.signInWithCredential(credential); return authResult.user; }As a note I got it working with iOS and Android through firebase.
But you are not using Firebase Hosting backend to catch the callback. ("https://xxxproject.web.app/__/auth/handler")
I'm having trouble using Firebase Hosting as handler server, getting the error "The requested action is invalid.".
Does anyone got the same problem? Any help is welcome.
from dart_packages.
@houdayec it is not supported to use the firebase hosted backend as the callback, see our README for instructions, and an example server which you need to set up to use Android.
from dart_packages.
I have the same question as @houdayec. Setting up a server seems unnecessary.
from dart_packages.
@houdayec easy: Not everyone is using Firebase. So we need to have an implementation which can be done without requiring a special provider/service.
While you might be using Firebase, plenty of consumers/companies might have other providers or own systems, so they can't/don't want to switch to Firebase.
from dart_packages.
@houdayec easy: Not everyone is using Firebase. So we need to have an implementation which can be done without requiring a special provider/service.
While you might be using Firebase, plenty of consumers/companies might have other providers or own systems, so they can't/don't want to switch to Firebase.
Of course not everyone is using Firebase. However, this is the most common / used MBaaS and to me, it should be an option as many people are facing an issue with it. It is not a matter of only providing a solution for Firebase, but also for Firebase. No need to switch for Firebase, it does not make sense. But your packages users might enjoy this feature.
from dart_packages.
@houdayec in our opinion the Firebase Auth package should do the full Firebase integration for Sign in with Apple on Android. For iOS, they could still refer to our package.
@houdayec you can also use the Firebase Cloud Function to implement the server, so this is technically not a blocker when already using Firebase.
from dart_packages.
@jessp01 is your bundle identifier really plate21
, normally it is something like com.company.app
Something weird is going on with the redirect for sure, so I would also suggest logging the redirect uri on the server and see if that looks alright
from dart_packages.
Hi @HenriBeck,
Thanks for your reply. Indeed, my bundle ID is different (that was just a test to see whether I'll get a different response with it).
Anyway, I'll add some debug prints in the NodeJS code. I'll update when I have additional findings/arrive at a resolution so that others may also benefit from it.
Thanks again,
from dart_packages.
I'm just trying to use Apple sign-in on iOS, along with Firebase. It was only through reading through this issue that it's become clear that I don't need to pay any attention to the instructions about setting up a server - the README does not mention anything about that step being specific to Android. I think it would be helpful if it did.
from dart_packages.
Hi @jessp01,
I'm curious if you found the solution as I'm facing exactly the same issue.
When I invoke
signInWithApple()
, from Android, I get to the Apple login screen (https://appleid.apple.com/auth..), I am successfully authenticated and asked if I'd like to continue. Upon clicking onContinue
(on the Apple page)
I received the exception from SignInWithApple.getAppleIDCredential(...
SignInWithAppleAuthorizationError(AuthorizationErrorCode.canceled, The user closed the Custom Tab)
The same exception is thrown when I close the Apple login screen manually.
I implemented the firebase function provided by @mpiparo. In the log, I can see the intent link was generated with the user's details.
from dart_packages.
@tstrg Just tried this with my Android app and signing in via apple and it worked OK.
The code I used can be viewed in this Gtihub repo. It might offer some clues as to why yours failed.
I did need another apple device (mac or phone) to validate the 2FA so perhaps this also needs setting up on your apple account?
from dart_packages.
@SoftWyer I've given it third try. I started from scratch and it starts working. Thanks for the code example.
from dart_packages.
<activity
android:name="com.aboutyou.dart_packages.sign_in_with_apple.SignInWithAppleCallback"
android:exported="true"
>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="signinwithapple" />
<data android:path="callback" />
</intent-filter>
</activity>
I have the same situation that this guy but I implemented the firebase cloud function (I check the result and I get the correct intent sintaxt callback):
When I invoke signInWithApple(), from Android, I get to the Apple login screen (https://appleid.apple.com/auth..), I am successfully authenticated and asked if I'd like to continue. Upon clicking on Continue (on the Apple page), I briefly see the Android logo and am then navigated to a blank screen with a throbber.
I think that I do not configure well the intent on ANDROID:
Some questions:
android:name="com.aboutyou.dart_packages.sign_in_with_apple.SignInWithAppleCallback"
has it to be this name or I have to change it? ...
Some one succesfull can share how he or she implement the intent on ANDROID...
Thank You
from dart_packages.
I made a dead simple python script for AWS Lambda (+ API Gateway) that does the redirect magic in case it helps anyone:
import json import base64 def lambda_handler(event, context): print(event) redirectActivityIdentifier = 'com.example.app' redirectData = base64.b64decode(event['body']).decode('ascii') redirect = f"intent://callback?{redirectData}#Intent;package={redirectActivityIdentifier};scheme=signinwithapple;end" print(f"redirecting to {redirect}") return { 'statusCode': 307, 'headers': {'Location': redirect}, 'body': json.dumps({}) }
Got Apple login through Firebase working on Android (can't seem to get Apple login to work on my iOS simulator funnily enough because of https://developer.apple.com/forums/thread/651533?page=10).
A Dart cloud functions solution would be handy for anyone using FIrebase as Firebase projects are tied to a Google Cloud project. https://dart.dev/server/google-cloud#functions-framework-for-dart
from dart_packages.
Note that the documentation for macOS/iOS can be found here: https://firebase.flutter.dev/docs/auth/social/#apple
Note that Android would work the same as long as you still use the redirect handler described in our README and not the one from Firebase.
from dart_packages.
you can test with:
curl -X POST -H "Content-Type:application/json" 'https://[firebase project id].web.app/app/callbacks/sign_in_with_apple' -d '{"test":"something"}'if all is working you should see the following test results:
Temporary Redirect. Redirecting to intent://callback?test=something#Intent;package=[your_android_app_package_id];scheme=signinwithapple;end
*Be sure to add the callback URL and domain in your Apple Dev account within the Web Authentication Configuration in your Service ID Sign-in-with-Apple config setup).
Could you please explain how should I run curl -X POST -H "Content-Type:application/json" 'https://[firebase project id].web.app/app/callbacks/sign_in_with_apple' -d '{"test":"something"}'
I am new in backend, I am using flutter and firestore, I made sure to have cloud_function and cloud_firestore packages and also linked my project to the backend and see { "projects": { "default": "<YOUR_FIREBASE_PROJECT_ID>" } }
Appreciate any suggestion.
from dart_packages.
Hi @tstrg,
May I ask what's your solution to your error?
Because my error is the same as yours. I'm able to authenticate but when I clicked continue it redirects to my app in playstore and when I open it the error shows:
SignInWithAppleAuthorizationError(AuthorizationErrorCode.canceled, The user closed the Custom Tab)
After setting all the Services IDs (don't forget to set that on Firebase Authentication for Apple page) and subdomains / URLs for firebase functions redirects, I also reach the redirect to playstore page not found.
Could this be something browser specific, which doesn't take my back to the fapp?
from dart_packages.
After entering the Apple ID and password, I cannot redirect to the app.
@alymbouras
Thanks for explaining these additional steps. I followed the steps and reached the point where I entered the Apple ID and password. But after continuing the process, I get an infinite circular indicator on a white screen of the google play store. It doesn't direct me to the app. I am on debug mode and also have tested the callback :
Temporary Redirect. Redirecting to intent://callback?key=value#Intent;package=com.example.backend_test_app;scheme=signinwithapple;end%
Any idea to fix this would be appreciated!
from dart_packages.
URL (https://us-central1-{YOUR-FIREBASE-PROJECT}.cloudfunctions.net/app/callbacks/sign_in_with_apple)
I am wondering if your deployed Function URL in Firebase if it includes "/callbacks/sign_in_with_apple" or not? I am using JavaScript so I converted the index.ts to index.js. I am not sure if this might cause the issues I mentioned at #91 (comment) or not!
from dart_packages.
Upon clicking on Continue (on the Apple page), I briefly see the Android logo and am then navigated to a blank screen with a throbber.
@angelserranoperez
I am facing the same problem with sign-in with Apple on android using firebase functions.
I am wondering if you have found any solution?!
from dart_packages.
Is there any documentation of steps for using Web only?
When I run in Debug the Sign In with Apple button opens a pop-up that says "invalid_request" "Invalid web redirect url." But the same code deployed to firebase does nothing but throw's an error in the console: "Uncaught Unsupported operation: Platform._operatingSystem"
Anyone run into this that could point me in the right direction?
My Flutter code looks identical to the Example code here with the obvious exception being the clientId is the Service ID identifier that has "sign in with apple" configured on it.
from dart_packages.
Related Issues (20)
- Sign in fails if no Apple account in device HOT 1
- no email in decoded jwt( identityToken ) HOT 4
- [SIGN_IN_WITH_APPLE]"Cannot Complete Request" Error after Clicking "Continue", Flutter Web HOT 1
- <data> tag failed HOT 3
- SSO with Apple in Flutter web not working
- SSO Apple sing in with firebase show Error Continue button not working , Flutter Web
- Apple delete account HOT 1
- sign_in_with_apple ^5.0.0 is forbidden HOT 1
- sign_in_with_apple: Migrate to `package:web` to support WASM HOT 6
- sign_in_with_apple: getCredentialState always returns authorized HOT 3
- Fix deprecation warnings
- Update dependencies (js) in sign_in_with_apple_web HOT 1
- iOS - Apple login not getting correct email and after successful login nothing happens HOT 2
- sign_in_with_apple web: TypeError when the sign in flow completes in version 6.0.0, works in 5.0.0 HOT 6
- I hope to add an option to remove Android dependencies, as Apple login is generally not needed on Android devices. HOT 4
- Add iOS privacy manifests HOT 4
- [sign_in_with_apple] Add privacy manifest file for iOS HOT 1
- Cannot find symbol ... sign_in_with_apple.SignInWithApplePlugin() HOT 5
- Facing issue in getting name in apple signin. HOT 4
- The Android Gradle plugin supports only Kotlin Gradle plugin version 1.5.20 and higher. HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dart_packages.