Skip to content

Instantly share code, notes, and snippets.

@zerolethanh
Created Apr 11, 2021
Embed
What would you like to do?
Apple Login with Expo and Firebase
import * as AppleAuthentication from 'expo-apple-authentication';
import React, { useEffect, useState } from 'react';
import { StyleSheet, View } from 'react-native';
import { auth } from '../../../config/firebaseConfig';
import { v4 } from 'uuid';
import * as firebase from 'firebase';
import { userColRef } from '../../../config/firestoreRefs';
function AppleLogin({ setInfo, onLoginDone }) {
const [isAppleLogin, setIsAppleLogin] = useState(false);
useEffect(() => {
(async () => {
const isApple = await AppleAuthentication.isAvailableAsync();
setIsAppleLogin(isApple);
})();
}, []);
if (!isAppleLogin) return null;
return (
<View style={styles.container}>
<AppleAuthentication.AppleAuthenticationButton
buttonType={AppleAuthentication.AppleAuthenticationButtonType.SIGN_IN}
buttonStyle={AppleAuthentication.AppleAuthenticationButtonStyle.WHITE_OUTLINE}
cornerRadius={5}
style={styles.appleLoginBtn}
onPress={async () => {
try {
const credential = await AppleAuthentication.signInAsync({
requestedScopes: [
AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
AppleAuthentication.AppleAuthenticationScope.EMAIL,
],
});
// console.log({ credential });
const authCredential = new firebase.auth.OAuthProvider(
'apple.com',
).credential({
idToken: credential.identityToken,
rawNonce: v4(), // notice this isn't encoded
});
try {
const { user } = await auth.signInWithCredential(
authCredential);
if (!user)
return;
let userInfo = {
userId: user.uid,
email: user.email,
nickname: user?.displayName || '',
lastLogin: new Date(),
providerId: 'apple.com',
photoURL: user?.photoURL || '',
};
const snap = await userColRef().doc(user.uid).get();
// update last login if exists
if (snap.exists && snap.data()?.nickname) {
await userColRef().doc(user.uid).set({
lastLogin: new Date(),
}, { merge: true });
if (onLoginDone) onLoginDone({ ...userInfo, uid: userInfo.userId });
return;
}
// open dialog update nick name
if (setInfo)
setInfo({ ...userInfo, uid: userInfo.userId });
} catch (e) {
console.error(e);
}
// signed in
} catch (e) {
console.log(e);
if (auth?.currentUser)
await auth.signOut();
if (e.code === 'ERR_CANCELED') {
// handle that the user canceled the sign-in flow
} else {
// handle other errors
console.error(e);
alert(e.message);
}
}
}}
/>
</View>
);
}
export default AppleLogin;
const styles = StyleSheet.create({
container: { display: 'flex', alignItems: 'center', paddingTop: 20 },
appleLoginBtn: { width: 300, height: 44 },
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment