diff --git a/packages/desktop/src/app.tsx b/packages/desktop/src/app.tsx index e230e9e..81bba01 100644 --- a/packages/desktop/src/app.tsx +++ b/packages/desktop/src/app.tsx @@ -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( diff --git a/packages/desktop/src/firebase/connect.ts b/packages/desktop/src/firebase/connect.ts index 689003a..09636cb 100644 --- a/packages/desktop/src/firebase/connect.ts +++ b/packages/desktop/src/firebase/connect.ts @@ -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); diff --git a/packages/desktop/src/firebase/firestore.ts b/packages/desktop/src/firebase/firestore.ts new file mode 100644 index 0000000..d0e3e65 --- /dev/null +++ b/packages/desktop/src/firebase/firestore.ts @@ -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 = () => ({ + toFirestore: (data: T) => data, + fromFirestore: (snap: QueryDocumentSnapshot) => snap.data() as T, +}); + +const dataPoint = (collectionPath: string) => + doc(getFirestore(), collectionPath).withConverter(converter()); + +const db = { + users: dataPoint('users'), + user: (userId: string) => dataPoint(`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); + } +}; diff --git a/packages/desktop/src/providers/AuthProvider.tsx b/packages/desktop/src/providers/AuthProvider.tsx index 7be8aeb..d4c4d47 100644 --- a/packages/desktop/src/providers/AuthProvider.tsx +++ b/packages/desktop/src/providers/AuthProvider.tsx @@ -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({}); @@ -31,19 +33,24 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => { const [currentUser, setCurrentUser] = useState(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 ( - + {currentUser ? <>{children} : } );