invertase/react-native-apple-authentication

No name provided (solution: use first_name as first scope element, you get first_name ONE TIME ONLY, save it)

quiringk opened this issue ยท 20 comments

When I first implemented this library I could use the workaround in the FAQ answer to get the display name again (Settings > Apple ID, iCloud, iTunes & App Store > Password & Security > Apps Using Your Apple ID > Stop using). However, that's not working anymore. Email is provided but name isn't. I see my name correctly displayed in the window Apple opens when you click the button but it's not provided in the code when you authenticate.

Something else I noticed is that when you do the steps in the FAQ answer ^, and then open up Apple auth, the Name field in the action sheet that opens is filled out correctly but the blue circle next to it has an "x" instead of a checkmark. Idk if that matters but when I try to click the blue circle it asks me to fill my name out and then goes gray with the "x" still in it.

Screen Shot 2022-07-08 at 5 06 25 PM

Those are not under this library's control as far as I know? I mean, you need to send the scopes you want in:

if (!Object.hasOwnProperty.call(requestOptions, ['requestedScopes'])) {

but if you do that it should work?

This is how I've been requesting scopes which used to provide name when doing the FAQ workaround:

const appleAuthRequestResponse = await appleAuth.performRequest({
	requestedScopes: [appleAuth.Scope.EMAIL, appleAuth.Scope.FULL_NAME],
});

I dunno ๐Ÿคท the change velocity here makes snails look really fast https://github.com/invertase/react-native-apple-authentication/commits/main - so I am guessing this is something about the operating system or that particular user or set of users? I'm just guessing though. Nothing in this area has changed in forever in this library

@quiringk did u find a solution to this? @mikehardy appreciate your responses here but Name is something our team is not able to see under any condition. It is possible we are missing some detail. We have indeed tried out the example.

Our team is also experiencing this issue. Had been working flawlessly for months and then suddenly we don't get Name for first time users

@nikitph just straining for any ideas here, perhaps it is related to something about the user? Or the user's iOS version? Or ... I don't have a lot of ideas here, sorry

@mikehardy @kylesurowiec figured out a fix. hopefully it will save some time for other people. The order of requested scopes is important. when i switched to FULL_NAME as the first element things magically started working. Not sure why that is. Also the scopes object in the response from apple is empty. May be one of their APIs changed. Ahh software engineering :) hopefully it saves time for others. But still Mike, great library and thanks for ur work.

const appleAuthRequestResponse = await appleAuth.performRequest({
      requestedOperation: appleAuth.Operation.LOGIN,
      requestedScopes: [appleAuth.Scope.FULL_NAME, appleAuth.Scope.EMAIL],
    });

@nikitph Thanks for the reply. Pushing a new build now to test this out. Unfortunately we aren't able to repro this consistently on our side but I will report back in a couple weeks and see if this continues to show up in our logs or not.

Fascinating! If this is confirmed obviously we can change the docs asap. Thanks for the report

@mikehardy We ran an email campaign with 160k recipients and saw a ton of new user sign ups with Apple auth. Have yet to see this issue pop up since we implemented the suggested fix. Its looking like the order does matter for whatever reason. Appreciate the help @nikitph.

Hopefully this helps someone else out

Fantastic news, thanks for reporting back. Queued for a docs update if no one beats me to it ๐Ÿ˜

const appleAuthRequestResponse = await appleAuth.performRequest({
      requestedOperation: appleAuth.Operation.LOGIN,
      requestedScopes: [appleAuth.Scope.FULL_NAME, appleAuth.Scope.EMAIL],
    });

I already did it, but it is not working for me, name still is return null in the first time login.

I'll leave this open but I need to set crystal clear expectations: this is an apple problem.

That means no comments here saying "me too" will be useful at all. Do not leave a me too comment

Useful comments will be something like: "I logged this issue with Apple and they said..."

Or "I opened this up in a debugger to check the API calls the module makes and the return, and we are doing everything correctly, it must be an apple issue, and I opened a ticket with them."

Nothing else will be useful, it will just generate spam notifications.

I would love to know the real reason and a real solution for this, and I would be more than happy to collaborate on and/or merge a PR with a solution but I have no time or interest in receiving useless spam notifications.

Thank you!

I think I have resolved this problem by doing some thing like this, actually, the fullName already returns but just one times after we run appleAuth.performRequest if we do something like this and transfer to the server it will be null on the server.

    // Create a Firebase credential from the response
    const { identityToken, nonce } = appleAuthRequestResponse;
    const appleCredential = auth.AppleAuthProvider.credential(identityToken, nonce);
    // Sign the user in with the credential
    return await auth().signInWithCredential(appleCredential);

So I did some strict on clients like this after that we can get the fullName on the server. I hope it can help someone.

    const appleAuthRequestResponse = await appleAuth.performRequest({
      requestedOperation: appleAuth.Operation.LOGIN,
      requestedScopes: [appleAuth.Scope.FULL_NAME, appleAuth.Scope.EMAIL],
    });
    // Ensure Apple returned a user identityToken
    if (!appleAuthRequestResponse.identityToken) {
      throw new Error('Apple Sign-In failed - no identify token returned');
    }
    const name = appleAuthRequestResponse.fullName;
    const fullName = `${name?.givenName} ${name?.familyName}`;
    // Create a Firebase credential from the response
    const { identityToken, nonce } = appleAuthRequestResponse;
    const appleCredential = auth.AppleAuthProvider.credential(identityToken, nonce);
    // Sign the user in with the credential
    const authenticate = await auth().signInWithCredential(appleCredential);
    authenticate.user = { ...authenticate.user, displayName: fullName };
    return authenticate;

I think I have resolved this problem by doing some thing like this, actually, the fullName already returns but just one times after we run appleAuth.performRequest

Isn't this the correct behavior? You receive fullName if a user is authenticating for the first time and save their token along with their account info on the backend. On subsequent requests only their token is provided which you should be using to look up their account.

Am I missing something here?

Okay, so actually working as documented, literally in our first FAQ

https://github.com/invertase/react-native-apple-authentication#faqs

๐Ÿคท

Closing again

But you can save apple user id and use it on the second login attempt.

Stop commenting on this issue. Your issue is completely unrelated to this and you're pinging everyone