create user firestore boilerplate and logout function

This commit is contained in:
talksik
2022-05-28 11:45:47 -05:00
parent af32ad2565
commit 7c05f27199
4 changed files with 85 additions and 3 deletions
+2
View File
@@ -9,6 +9,8 @@ import { NirvanaTheme } from './mui/NirvanaTheme';
import { ElectronProvider } from './providers/ElectronProvider'; import { ElectronProvider } from './providers/ElectronProvider';
import { AuthProvider } from './providers/AuthProvider'; import { AuthProvider } from './providers/AuthProvider';
import './firebase/connect';
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render( root.render(
<React.StrictMode> <React.StrictMode>
+5
View File
@@ -2,9 +2,14 @@
import { initializeApp } from 'firebase/app'; import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth'; import { getAuth } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
import devConfig from './config/firebase.dev.config.json'; import devConfig from './config/firebase.dev.config.json';
export const firebaseApp = initializeApp(devConfig); export const firebaseApp = initializeApp(devConfig);
export const firebaseAuth = getAuth(firebaseApp); export const firebaseAuth = getAuth(firebaseApp);
// Initialize Cloud Firestore and get a reference to the service
export const firestore = getFirestore(firebaseApp);
@@ -0,0 +1,66 @@
//TODO: move all of this to core or common and separate out files
import {
setDoc,
getFirestore,
doc,
collection,
QueryDocumentSnapshot,
Timestamp,
FieldValue,
} from 'firebase/firestore';
import { User as FirebaseUser } from 'firebase/auth';
/**
* UTILS
*/
const converter = <T>() => ({
toFirestore: (data: T) => data,
fromFirestore: (snap: QueryDocumentSnapshot) => snap.data() as T,
});
const dataPoint = <T>(collectionPath: string) =>
doc(getFirestore(), collectionPath).withConverter(converter<T>());
const db = {
users: dataPoint<User[]>('users'),
user: (userId: string) => dataPoint<User>(`users/${userId}`),
};
export class User {
lastUpdatedDate?: Timestamp;
constructor(
public uid: string,
public providerId: string,
public email: string,
public displayName?: string,
public photoUrl?: string,
public phoneNumber?: string,
public createdDate: Timestamp = Timestamp.now(),
) {}
}
// enum COLLECTION {
// users = 'users',
// }
export const createUser = async (user: FirebaseUser) => {
try {
await setDoc(
db.user(user.uid),
new User(
user.uid,
user.providerId,
user.email,
user.displayName,
user.photoURL,
user.phoneNumber,
),
{ merge: true },
);
} catch (e) {
console.error('Error creating user: ', e);
}
};
@@ -17,9 +17,11 @@ import {
getAuth, getAuth,
} from 'firebase/auth'; } from 'firebase/auth';
import { useSnackbar } from 'notistack'; import { useSnackbar } from 'notistack';
import { createUser } from '../firebase/firestore';
interface IAuthContext { interface IAuthContext {
user?: FirebaseUser; user?: FirebaseUser;
logout?: () => void;
} }
const AuthContext = React.createContext<IAuthContext>({}); const AuthContext = React.createContext<IAuthContext>({});
@@ -31,19 +33,24 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
const [currentUser, setCurrentUser] = useState<FirebaseUser>(null); const [currentUser, setCurrentUser] = useState<FirebaseUser>(null);
useEffect(() => { useEffect(() => {
const authListener = onAuthStateChanged(firebaseAuth, (user) => { const authListener = onAuthStateChanged(firebaseAuth, async (user) => {
console.log('auth changed!!!!', user); console.log('auth changed!!!!', user);
if (user) { if (user) {
// TODO: add user to user's table with new sign in infp
await createUser(user);
setCurrentUser(user); setCurrentUser(user);
} else { } else {
// User is signed out // User is signed out
// ... // ...
enqueueSnackbar('Logged out');
setCurrentUser(null);
} }
}); });
return () => authListener(); return () => authListener();
}, [setCurrentUser]); }, [setCurrentUser, enqueueSnackbar]);
useEffect(() => { useEffect(() => {
const tokenListener = window.electronAPI.once( const tokenListener = window.electronAPI.once(
@@ -86,8 +93,10 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
return () => tokenListener(); return () => tokenListener();
}, [enqueueSnackbar]); }, [enqueueSnackbar]);
const logout = useCallback(() => firebaseAuth.signOut(), []);
return ( return (
<AuthContext.Provider value={{ user: currentUser }}> <AuthContext.Provider value={{ user: currentUser, logout }}>
{currentUser ? <>{children}</> : <Login />} {currentUser ? <>{children}</> : <Login />}
</AuthContext.Provider> </AuthContext.Provider>
); );