Skip to content

Instantly share code, notes, and snippets.

@gregfenton
Created February 8, 2022 03:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gregfenton/f0d30ef39803f7016498ca669bf2bea0 to your computer and use it in GitHub Desktop.
Save gregfenton/f0d30ef39803f7016498ca669bf2bea0 to your computer and use it in GitHub Desktop.
A React/React-Native authentication provider that uses the Context API to make authentication & profile info available to "the rest of the app"
import React, {createContext, useEffect, useState} from 'react';
import auth from '@react-native-firebase/auth'; // or from 'firebase/auth';
import Loading from '../components/Loading';
import {myFirestore} from '../common/firebase.js';
export const AuthContext = createContext({});
export const AuthProvider = (props) => {
const children = props.children;
const [user, setUser] = useState(null);
const [profile, setProfile] = useState(null);
const [authLoading, setAuthLoading] = useState(true);
const loginFunction = async (email, password) => {
try {
let userCredential = await auth().signInWithEmailAndPassword(email, password);
let user = userCredential.user;
if (!user?.uid) {
let msg = `No UID found after signIn!`;
console.error(msg);
}
if (user) {
console.log(`Logged in as uid(${user.uid}) email(${user.email})`);
}
setUser(user);
} catch (ex) {
let msg = `Login failure for email(${email}: ${ex.message})`;
console.error(msg);
}
};
const logoutFunction = async () => {
try {
setUser(null); // shut down the listeners
await auth().signOut();
} catch (ex) {
console.error(ex);
}
};
// hook into Firebase Authentication
useEffect(() => {
let unsubscribe = auth().onAuthStateChanged((user) => {
// if user is null, then we force them to login
if (user) {
setUser(user);
}
setAuthLoading(false);
});
return unsubscribe;
}, []);
// listen to the user profile (FS User doc)
useEffect(() => {
const listenToUserDoc = async (uid) => {
let unsubscribe = await myFirestore.doc(`users/${uid}`).onSnapshot(docSnap => setProfile(docSnap.data()));
return unsubscribe;
};
let unsubscribe;
if (user?.uid) {
listenToUserDoc(user.uid)
.then((unsub) => {
unsubscribe = unsub;
})
.catch((ex) =>
console.error(`ERROR: ActScreen useEffect: ${ex.message}`)
);
return () => {
unsubscribe && unsubscribe();
};
} else if (!user) {
setAuthLoading(true);
}
}, [user, setProfile]);
if (authLoading) {
return <Loading />;
}
const theValues = {
authLoading,
user,
profile,
login: loginFunction,
logout: logoutFunction,
};
return (
<AuthContext.Provider value={theValues}>
{children}
</AuthContext.Provider>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment