-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfirebaseAuth.js
More file actions
116 lines (108 loc) · 4.12 KB
/
firebaseAuth.js
File metadata and controls
116 lines (108 loc) · 4.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { Platform } from 'react-native';
import { getApp } from '@react-native-firebase/app';
import {
getAuth,
signInWithCredential,
signOut,
getIdToken,
GoogleAuthProvider,
OAuthProvider,
} from '@react-native-firebase/auth';
import { GoogleSignin } from '@react-native-google-signin/google-signin';
import {
appleAuth,
appleAuthAndroid,
} from '@invertase/react-native-apple-authentication';
// Replace these three constants with values from your own Firebase / Apple
// Developer / Google Cloud console before running on a real device.
// APPLE_SERVICES_ID — Apple "Services ID" used for Sign in with Apple
// on Android (`com.your.app.signin`).
// APPLE_REDIRECT_URI — Firebase Auth handler URL for your project,
// shape: `https://<firebase-project-id>.firebaseapp.com/__/auth/handler`.
// GOOGLE_WEB_CLIENT_ID — OAuth 2.0 Web client id from Google Cloud
// console (Firebase auto-creates one).
const APPLE_SERVICES_ID = 'REPLACE_WITH_APPLE_SERVICES_ID';
const APPLE_REDIRECT_URI =
'https://your-firebase-project-id.firebaseapp.com/__/auth/handler';
const GOOGLE_WEB_CLIENT_ID = 'REPLACE_WITH_GOOGLE_WEB_CLIENT_ID';
const randomNonce = () => {
let s = '';
for (let i = 0; i < 32; i++) s += Math.floor(Math.random() * 16).toString(16);
return s;
};
const auth = () => getAuth(getApp());
/**
* Sign in with Google → Firebase credential → Firebase ID token.
* @returns {Promise<{firebaseIdToken: string, appleRefreshToken: null}>}
*/
export const signInWithGoogle = async () => {
GoogleSignin.configure({ webClientId: GOOGLE_WEB_CLIENT_ID });
await GoogleSignin.hasPlayServices({ showPlayServicesUpdateDialog: true });
const result = await GoogleSignin.signIn();
const idToken = result?.idToken ?? result?.data?.idToken;
if (!idToken) throw new Error('Google Sign-In returned no ID token');
const cred = GoogleAuthProvider.credential(idToken);
const { user } = await signInWithCredential(auth(), cred);
const firebaseIdToken = await getIdToken(user);
return { firebaseIdToken, appleRefreshToken: null };
};
/**
* Sign in with Apple → Firebase credential → Firebase ID token.
* On iOS: native Apple sheet. On Android: web-based OAuth via Services ID.
* @returns {Promise<{firebaseIdToken: string, appleRefreshToken: string|null}>}
*/
export const signInWithApple = async () => {
if (Platform.OS === 'ios') {
const res = await appleAuth.performRequest({
requestedOperation: appleAuth.Operation.LOGIN,
requestedScopes: [appleAuth.Scope.EMAIL, appleAuth.Scope.FULL_NAME],
});
if (!res.identityToken)
throw new Error('Apple Sign-In returned no identity token');
const provider = new OAuthProvider('apple.com');
const cred = provider.credential({
rawNonce: res.nonce,
idToken: res.identityToken,
});
const { user } = await signInWithCredential(auth(), cred);
return {
firebaseIdToken: await getIdToken(user),
appleRefreshToken: res.authorizationCode ?? null,
};
}
if (Platform.OS === 'android') {
appleAuthAndroid.configure({
nonce: randomNonce(),
clientId: APPLE_SERVICES_ID,
redirectUri: APPLE_REDIRECT_URI,
scope: appleAuthAndroid.Scope.ALL,
responseType: appleAuthAndroid.ResponseType.ALL,
});
const res = await appleAuthAndroid.signIn();
if (!res.id_token)
throw new Error('Apple Sign-In (Android) returned no ID token');
const provider = new OAuthProvider('apple.com');
const cred = provider.credential({
rawNonce: res.nonce,
idToken: res.id_token,
});
const { user } = await signInWithCredential(auth(), cred);
return {
firebaseIdToken: await getIdToken(user),
appleRefreshToken: res.code ?? null,
};
}
throw new Error('Apple Sign-In not supported on this platform');
};
/**
* Sign out of Firebase + Google. Apple has no client-side sign-out — token
* revocation happens server-side during account deletion.
*/
export const signOutFirebase = async () => {
try {
await signOut(auth());
} catch {}
try {
await GoogleSignin.signOut();
} catch {}
};