I have implemented combining multiple login methods with one account in my mobile application written in Flutter (I also had a problem with this, but it was solved in this topic How to implement sign in methods merging in flutter app using parse server?).
On the backend side, I use a parse server. Generally, when I am logged in to the account using e.g. Apple Sign In, I can easily add additional accounts, e.g. Facebook Sign In or Google Sign (because I have access to the data of the account I am currently logged in to).
The problem occurs when, for example, I have an account connected only to Apple Sign In, which is based on the e-mail mail@example.com, but When i created that account I clicked that i refuse to show my e-mail address so apple encrypts it like example@privaterelay.appleid.com.
When I am logged out of this account and I want, e.g. log in using Facebook sign in or Google sign in (I also use mail@example.com on these accounts), unfortunately it creates a new account for me because my email mail@example.com does not equal example@privaterelay.appleid.com.
I presume that in the case of the email address sharing policy variable, I will have to use some other value to associate different login methods belonging to one user while he is logged out.
If the email you get from Apple sign in doesn't satisfy your needs, then best option is to capture it on your own. After all for linking the user, which I described in previous answer, you just need to retrieve identityToken
and userIdentifier
from Sign in with Apple. Other data like email and full name can be retrieved from user separately. It does add some extra steps for user to sign up, but it has to be done just once - on the first sign up.
Instead of getting email from the request you make when using Sign in with Apple, you could specify just fullName
in scope of the request and after successful sign in prompt the user to enter his email. Your request with just full name could look like:
final AuthorizationCredentialAppleID credential = await SignInWithApple.getAppleIDCredential(
scopes: [AppleIDAuthorizationScopes.fullName],
);
Apple clearly states that you can use one or more of these values when defining scope in their Swift developer docs. It also states in Apple JS docs that you can also choose to request both, or neither.
After you collected all the values that ParseUser.loginWith
method requires you can login user into parse server. This allows you to get email which user may also use when signing up with other 3rd party providers.
One additional improvement you will have to make is when you're checking if user is already signed up with apple. This validation now has to be done with userIdentifier
, because you're not retrieving email from Apple sign in. Making this clear, you will have to query user in Parse database by apple userIdentifier
in order to check for existing user.
Tinder is also making use of this approach so it's not something new in mobile community. Try to test their logic for Sign up with Apple to see it in action.