Closed arielhasidim closed 2 years ago
When I try this on iOS 15, the code crashes when it gets to:
const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
There is no 'subtle' in the window.crypto, it is undefined. Apparently crypto is only supported under secure contexts (e.g. https) (via: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto), and some web comments have suggested crypto.subtle was present in mobile Safari until recently, but was removed, which could explain why it's not working for me. Ionic is serving the internal pages on http (or other capacitor/app/file schemes), which aren't 'secure'.
Anyone else have this issue? I hate to have to send the nonce off-device to get a SHA hash, but not finding a good alternative.
AWS has an Apache 2.0-licensed implementation of SHA256 that uses crypto.subtle if it exists, and implements directly if not: https://www.npmjs.com/package/@aws-crypto/sha256-browser
so, npm i @aws-crypto/sha256-browser
and then
import { Sha256 } from '@aws-crypto/sha256-browser';
.....
async sha256(message) {
const hash = new Sha256();
hash.update(message);
const digest = await hash.digest();
// convert ArrayBuffer to Array
const hashArray = Array.from(new Uint8Array(digest));
// convert bytes to hex string
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
return hashHex;
}
worked for me.
Hi everyone!
I'm having a similar problem.
In my context, I am already authenticated anonymously in web context, so I have to link this anonymous user using appleCredential
and linkWithCredential
method of firebase auth module. The link works, but not e-mail was set (in Firebase Console, it shows a single "-" instead of user e-mail) and the workaround for this was to update user e-mail manually later in this process.
My problem is with signInWithCredential
, that has been executed after the account has been linked. It always throws this error:
Domain: Code: -1001 NSLocalizedDescription: Duplicate credential received. Please try again with a new credential.
If anyone have thoughts about this, I'll apreciate :)
After a while trying and reading about this problem, I could figure it out. To solve this, I had to retrieve the appleCredential
back from the error generated from linkWithCredential
.
If the user is signing-up, the auth.currentUser
contains an anonymous firebase auth user and it will be converted into an non-anonymous user, linking with the apple credential correctly. Later, when user signs-out and signs-in again, the link will failed with auth/credential-already-in-use
error. Following the firebase auth docs and other topics, this error object contains the firebase credential at error.credential
or error.userInfo.authCredential
(I am not sure in which one, it didn't becomes very clear to me), then I used this credential it in signInWithCredential
, which worked gracefully then.
Follows the implementation for further references.
try {
userCred = await auth.currentUser?.linkWithCredential(appleCredential);
} catch (error: any) {
const errorCode = error.code || "";
if (errorCode === "auth/credential-already-in-use") {
/*
auth/credential-already-in-use
Thrown if the account corresponding to the credential already exists among your users,
or is already linked to a Firebase User. For example, this error could be thrown
if you are upgrading an anonymous user to a Google user by linking a Google credential to it
and the Google credential used is already associated with an existing Firebase Google user.
The fields error.email, error.phoneNumber, and error.credential (firebase.auth.AuthCredential) may be provided,
depending on the type of credential.
You can recover from this error by signing in with error.credential directly via firebase.auth.Auth.signInWithCredential.
*/
console.warn("Credential already in use");
const errorCred = error.userInfo?.authCredential || error.credential;
if (errorCred) {
userCred = await auth.signInWithCredential(errorCred);
}
} else {
throw error;
}
}
Describe the problem apple-sign-in plugin v1.0.1 worked great for me with: "@capacitor/cli": "3.3.2", "@capacitor/ios": "^3.3.2", "@capacitor/angular": "^2.0.0", "@angular/cli": "^13.1.1", Angular CLI: 13.1.1
BUT when I tried to pass the credentials to Firebase SDK I encountered:
ERROR {"code":"auth/missing-or-invalid-nonce","message":"Nonce is missing in the request."}
(as mentioned also in this https://github.com/capacitor-community/apple-sign-in/issues/60#issuecomment-947929185)Solution According to this documentation, when using Firebase's
firebase.auth().signInWithCredential
, you also required to pass "raw nonce" that, after being hashed, suppose to match the nonce that is contained in theidentityToken
we get back from this plugin (not sure if this is a new requirement in Firebase's side).THE CATCH IS that you need to hash the nonce before you pass it in the
SignInWithAppleOptions
. I used this snippet for hashing nonce: