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 { AuthProvider } from './providers/AuthProvider';
import './firebase/connect';
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
<React.StrictMode>
+5
View File
@@ -2,9 +2,14 @@
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
// eslint-disable-next-line @typescript-eslint/no-var-requires
import devConfig from './config/firebase.dev.config.json';
export const firebaseApp = initializeApp(devConfig);
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,
} from 'firebase/auth';
import { useSnackbar } from 'notistack';
import { createUser } from '../firebase/firestore';
interface IAuthContext {
user?: FirebaseUser;
logout?: () => void;
}
const AuthContext = React.createContext<IAuthContext>({});
@@ -31,19 +33,24 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
const [currentUser, setCurrentUser] = useState<FirebaseUser>(null);
useEffect(() => {
const authListener = onAuthStateChanged(firebaseAuth, (user) => {
const authListener = onAuthStateChanged(firebaseAuth, async (user) => {
console.log('auth changed!!!!', user);
if (user) {
// TODO: add user to user's table with new sign in infp
await createUser(user);
setCurrentUser(user);
} else {
// User is signed out
// ...
enqueueSnackbar('Logged out');
setCurrentUser(null);
}
});
return () => authListener();
}, [setCurrentUser]);
}, [setCurrentUser, enqueueSnackbar]);
useEffect(() => {
const tokenListener = window.electronAPI.once(
@@ -86,8 +93,10 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
return () => tokenListener();
}, [enqueueSnackbar]);
const logout = useCallback(() => firebaseAuth.signOut(), []);
return (
<AuthContext.Provider value={{ user: currentUser }}>
<AuthContext.Provider value={{ user: currentUser, logout }}>
{currentUser ? <>{children}</> : <Login />}
</AuthContext.Provider>
);