naim-firebase-auth-wrapper
Version:
React components and hooks for Firebase Authentication and Firestore with Mantine UI
942 lines • 34.6 kB
JavaScript
/**
* Firestore service module
*
* This module provides Firestore service functions for browser environments.
*/
import { collection, doc, getDocs, getDoc, setDoc, updateDoc, deleteDoc, where, query, getFirestore } from 'firebase/firestore';
import { updateProfile } from 'firebase/auth';
import { getApp, getFirebaseAuth } from '../firebase/config';
// User Profile Services
export const createUserProfile = async (userId, userData) => {
console.log('[Firestore Service] Creating user profile:', { userId });
// Get a fresh reference to Firestore
const currentDb = getFirestore();
if (!currentDb) {
console.error('[Firestore Service] Firestore not initialized in createUserProfile');
throw new Error('Firestore not initialized');
}
try {
await setDoc(doc(currentDb, 'users', userId), {
...userData,
createdAt: new Date()
});
return userId;
}
catch (error) {
console.error('[Firestore Service] Error creating user profile:', error);
throw error;
}
};
export const getUserProfile = async (userId) => {
console.log('[Firestore Service] Getting user profile:', { userId });
// Get a fresh reference to Firestore
const currentDb = getFirestore();
if (!currentDb) {
console.error('[Firestore Service] Firestore not initialized in getUserProfile');
throw new Error('Firestore not initialized');
}
try {
const userDoc = await getDoc(doc(currentDb, 'users', userId));
if (!userDoc.exists())
return null;
return { uid: userId, ...userDoc.data() };
}
catch (error) {
console.error('[Firestore Service] Error getting user profile:', error);
throw error;
}
};
export const updateUserProfile = async (userId, userData) => {
console.log('[Firestore Service] Updating user profile:', { userId });
// Get a fresh reference to Firestore
const currentDb = getFirestore();
if (!currentDb) {
console.error('[Firestore Service] Firestore not initialized in updateUserProfile');
throw new Error('Firestore not initialized');
}
try {
// Update Firestore document
await updateDoc(doc(currentDb, 'users', userId), userData);
// Also update Auth user if displayName or photoURL is provided
if (userData.displayName || userData.photoURL) {
const auth = getFirebaseAuth();
if (auth && auth.currentUser && auth.currentUser.uid === userId) {
console.log('[Firestore Service] Also updating Auth user profile');
await updateProfile(auth.currentUser, {
displayName: userData.displayName,
photoURL: userData.photoURL
});
}
else {
console.log('[Firestore Service] Cannot update Auth user profile - user not logged in or mismatch');
}
}
return userId;
}
catch (error) {
console.error('[Firestore Service] Error updating user profile:', error);
throw error;
}
};
export const deleteUserProfile = async (userId) => {
console.log('[Firestore Service] Deleting user profile:', { userId });
// Get a fresh reference to Firestore
const currentDb = getFirestore();
if (!currentDb) {
console.error('[Firestore Service] Firestore not initialized in deleteUserProfile');
throw new Error('Firestore not initialized');
}
try {
await deleteDoc(doc(currentDb, 'users', userId));
return userId;
}
catch (error) {
console.error('[Firestore Service] Error deleting user profile:', error);
throw error;
}
};
// Create a new organization
export const createOrganization = async (orgData) => {
console.log('[Firestore Service] Creating organization:', orgData);
// Get a fresh reference to Firestore
console.log('[Firestore Service] Getting Firestore instance for createOrganization');
const currentDb = getFirestore();
if (!currentDb) {
console.error('[Firestore Service] Firestore not initialized in createOrganization');
throw new Error('Firestore not initialized');
}
console.log('[Firestore Service] Firestore instance obtained, creating document');
try {
const orgRef = doc(collection(currentDb, 'organizations'));
const orgId = orgRef.id;
const timestamp = new Date();
console.log(`[Firestore Service] Setting organization document with ID: ${orgId}`);
await setDoc(orgRef, {
id: orgId,
...orgData,
createdAt: timestamp,
members: [{
userId: orgData.ownerId,
role: 'owner',
joinedAt: timestamp
}]
});
// Add organization to user's organizations
if (orgData.ownerId) {
console.log(`[Firestore Service] Adding organization ${orgId} to user ${orgData.ownerId}`);
const userRef = doc(currentDb, 'users', orgData.ownerId);
const userDoc = await getDoc(userRef);
if (userDoc.exists()) {
const userData = userDoc.data();
const organizations = userData.organizations || [];
console.log(`[Firestore Service] Updating user's organizations list`);
await updateDoc(userRef, {
organizations: [...organizations, {
orgId,
role: 'owner'
}],
currentOrganization: orgId
});
console.log(`[Firestore Service] User's organizations list updated`);
}
else {
console.warn(`[Firestore Service] User document not found for ID: ${orgData.ownerId}`);
}
}
console.log('[Firestore Service] Organization created successfully:', orgId);
return orgId;
}
catch (error) {
console.error('[Firestore Service] Error creating organization:', error);
throw error;
}
};
// Get organization by ID
export const getOrganization = async (orgId) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
const orgDocRef = doc(currentDb, 'organizations', orgId);
const orgDoc = await getDoc(orgDocRef);
if (orgDoc.exists()) {
return { id: orgDoc.id, ...orgDoc.data() };
}
return undefined;
}
catch (error) {
console.error('Error getting organization:', error);
throw error;
}
};
// Get user's organizations
export const getUserOrganizations = async (userId) => {
console.log(`[Firestore Service] Getting organizations for user: ${userId}`);
try {
console.log('[Firestore Service] Getting Firestore instance for getUserOrganizations');
const currentDb = getFirestore();
if (!currentDb) {
console.error('[Firestore Service] Firestore not initialized in getUserOrganizations');
throw new Error('Firestore not initialized');
}
// Get user profile to get organization IDs
console.log(`[Firestore Service] Getting user profile for ${userId}`);
const userProfile = await getUserProfile(userId);
if (!userProfile || !userProfile.organizations || userProfile.organizations.length === 0) {
console.log(`[Firestore Service] No organizations found for user ${userId}`);
return [];
}
console.log(`[Firestore Service] Found ${userProfile.organizations.length} organizations for user ${userId}`);
// Get all organizations the user is a member of
const orgIds = userProfile.organizations.map(org => org.orgId);
const orgs = [];
for (const orgId of orgIds) {
console.log(`[Firestore Service] Fetching organization ${orgId}`);
const org = await getOrganization(orgId);
if (org) {
orgs.push(org);
}
else {
console.warn(`[Firestore Service] Organization ${orgId} not found`);
}
}
console.log(`[Firestore Service] Returning ${orgs.length} organizations for user ${userId}`);
return orgs;
}
catch (error) {
console.error('[Firestore Service] Error getting user organizations:', error);
throw error;
}
};
// Set current organization for user
export const setCurrentOrganization = async (userId, orgId) => {
console.log('[Firestore Service] Setting current organization:', { userId, orgId });
// Get a fresh reference to Firestore
console.log('[Firestore Service] Getting Firestore instance for setCurrentOrganization');
const currentDb = getFirestore();
if (!currentDb) {
console.error('[Firestore Service] Firestore not initialized in setCurrentOrganization');
console.error('[Firestore Service] Firebase app status:', getApp() ? 'Available' : 'Not available');
throw new Error('Firestore not initialized');
}
console.log('[Firestore Service] Firestore instance obtained, updating document');
try {
const userRef = doc(currentDb, 'users', userId);
console.log(`[Firestore Service] Updating user document ${userId} with currentOrganization: ${orgId}`);
await updateDoc(userRef, {
currentOrganization: orgId
});
console.log('[Firestore Service] Current organization updated successfully');
}
catch (error) {
console.error('[Firestore Service] Error updating current organization:', error);
throw error;
}
};
// Add user to organization
export const addUserToOrganization = async (orgId, userId, role) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
// Get the organization
const orgRef = doc(currentDb, 'organizations', orgId);
const orgDoc = await getDoc(orgRef);
if (!orgDoc.exists()) {
throw new Error(`Organization ${orgId} not found`);
}
const orgData = orgDoc.data();
// Check if user is already a member
const existingMember = orgData.members.find(m => m.userId === userId);
if (existingMember) {
// Update role if different
if (existingMember.role !== role) {
const updatedMembers = orgData.members.map(m => m.userId === userId ? { ...m, role } : m);
await updateDoc(orgRef, {
members: updatedMembers
});
}
}
else {
// Add user to organization
const newMember = {
userId,
role,
joinedAt: new Date()
};
await updateDoc(orgRef, {
members: [...orgData.members, newMember]
});
}
// Update user's organizations
const userRef = doc(currentDb, 'users', userId);
const userDoc = await getDoc(userRef);
if (userDoc.exists()) {
const userData = userDoc.data();
const userOrgs = userData.organizations || [];
// Check if user already has this organization
const hasOrg = userOrgs.some(org => org.orgId === orgId);
if (!hasOrg) {
await updateDoc(userRef, {
organizations: [...userOrgs, { orgId, role }]
});
}
else {
// Update role if different
const updatedOrgs = userOrgs.map(org => org.orgId === orgId ? { ...org, role } : org);
await updateDoc(userRef, {
organizations: updatedOrgs
});
}
}
}
catch (error) {
console.error('Error adding user to organization:', error);
throw error;
}
};
// Get all users (for admin dashboard)
export const getAllUsers = async () => {
console.log('[Firestore Service] Getting all users');
// Get a fresh reference to Firestore
const currentDb = getFirestore();
if (!currentDb) {
console.error('[Firestore Service] Firestore not initialized in getAllUsers');
throw new Error('Firestore not initialized');
}
try {
const usersSnapshot = await getDocs(collection(currentDb, 'users'));
return usersSnapshot.docs.map(doc => ({ uid: doc.id, ...doc.data() }));
}
catch (error) {
console.error('[Firestore Service] Error getting all users:', error);
throw error;
}
};
// Delete a user
export const deleteUser = async (userId) => {
console.log('[Firestore Service] Deleting user:', { userId });
// Get a fresh reference to Firestore
const currentDb = getFirestore();
if (!currentDb) {
console.error('[Firestore Service] Firestore not initialized in deleteUser');
throw new Error('Firestore not initialized');
}
try {
await deleteDoc(doc(currentDb, 'users', userId));
}
catch (error) {
console.error('[Firestore Service] Error deleting user:', error);
throw error;
}
};
// Update organization
export const updateOrganization = async (orgId, orgData) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
await updateDoc(doc(currentDb, 'organizations', orgId), {
...orgData,
updatedAt: new Date()
});
return orgId;
}
catch (error) {
console.error('Error updating organization:', error);
throw error;
}
};
// Delete organization
export const deleteOrganization = async (orgId) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
await deleteDoc(doc(currentDb, 'organizations', orgId));
return orgId;
}
catch (error) {
console.error('Error deleting organization:', error);
throw error;
}
};
// Get organization members
export const getOrganizationMembers = async (orgId) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
const orgDocRef = doc(currentDb, 'organizations', orgId);
const orgDoc = await getDoc(orgDocRef);
if (!orgDoc.exists()) {
throw new Error('Organization not found');
}
const orgData = orgDoc.data();
const members = orgData.members || [];
const userProfiles = [];
for (const member of members) {
const userDocRef = doc(currentDb, 'users', member.userId);
const userDoc = await getDoc(userDocRef);
if (userDoc.exists()) {
userProfiles.push({
uid: userDoc.id,
...userDoc.data(),
role: member.role
});
}
}
return userProfiles;
}
catch (error) {
console.error('Error getting organization members:', error);
throw error;
}
};
// Remove user from organization
export const removeUserFromOrganization = async (orgId, userId) => {
console.log('[Firestore Service] Removing user from organization:', { orgId, userId });
// Get a fresh reference to Firestore
const currentDb = getFirestore();
if (!currentDb) {
console.error('[Firestore Service] Firestore not initialized in removeUserFromOrganization');
throw new Error('Firestore not initialized');
}
try {
// Get the organization
const orgRef = doc(currentDb, 'organizations', orgId);
const orgSnap = await getDoc(orgRef);
if (!orgSnap.exists()) {
throw new Error('Organization not found');
}
const org = orgSnap.data();
// Remove user from members array
const updatedMembers = org.members.filter(member => member.userId !== userId);
// Update organization
await updateDoc(orgRef, {
members: updatedMembers
});
// Update user's organizations
const userRef = doc(currentDb, 'users', userId);
const userSnap = await getDoc(userRef);
if (userSnap.exists()) {
const userData = userSnap.data();
const userOrgs = userData.organizations || [];
// Remove organization from user's organizations
const updatedOrgs = userOrgs.filter(org => org.orgId !== orgId);
await updateDoc(userRef, {
organizations: updatedOrgs
});
}
}
catch (error) {
console.error('[Firestore Service] Error removing user from organization:', error);
throw error;
}
};
// User Session Services
export const createUserSession = async (sessionData) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
const sessionRef = doc(collection(currentDb, 'sessions'));
await setDoc(sessionRef, {
...sessionData,
createdAt: new Date()
});
return sessionRef.id;
}
catch (error) {
console.error('Error creating user session:', error);
throw error;
}
};
export const getUserSession = async (sessionId) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
const sessionDocRef = doc(currentDb, 'sessions', sessionId);
const sessionDoc = await getDoc(sessionDocRef);
if (sessionDoc.exists()) {
return { id: sessionDoc.id, ...sessionDoc.data() };
}
return undefined;
}
catch (error) {
console.error('Error getting user session:', error);
throw error;
}
};
export const updateUserSession = async (sessionId, sessionData) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
await updateDoc(doc(currentDb, 'sessions', sessionId), {
...sessionData,
updatedAt: new Date()
});
return sessionId;
}
catch (error) {
console.error('Error updating user session:', error);
throw error;
}
};
export const deleteUserSession = async (sessionId) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
await deleteDoc(doc(currentDb, 'sessions', sessionId));
return sessionId;
}
catch (error) {
console.error('Error deleting user session:', error);
throw error;
}
};
// Invitation Services
export const createInvitation = async (invitationData, callbacks) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
const invitationRef = doc(collection(currentDb, 'invitations'));
// Generate a token for the invitation
const token = generateInvitationToken();
await setDoc(invitationRef, {
...invitationData,
token,
createdAt: new Date()
});
if (callbacks?.onSuccess) {
callbacks.onSuccess(invitationRef.id);
}
return invitationRef.id;
}
catch (error) {
console.error('Error creating invitation:', error);
if (callbacks?.onError) {
callbacks.onError(error);
}
throw error;
}
};
export const getInvitation = async (invitationId) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
const invitationDocRef = doc(currentDb, 'invitations', invitationId);
const invitationDoc = await getDoc(invitationDocRef);
if (invitationDoc.exists()) {
return { id: invitationDoc.id, ...invitationDoc.data() };
}
return undefined;
}
catch (error) {
console.error('Error getting invitation:', error);
throw error;
}
};
export const getInvitationByToken = async (token) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
const invitationsRef = collection(currentDb, 'invitations');
const q = query(invitationsRef, where('token', '==', token));
const querySnapshot = await getDocs(q);
if (!querySnapshot.empty) {
const doc = querySnapshot.docs[0];
return { id: doc.id, ...doc.data() };
}
return null;
}
catch (error) {
console.error('Error getting invitation by token:', error);
throw error;
}
};
export const updateInvitation = async (invitationId, invitationData) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
await updateDoc(doc(currentDb, 'invitations', invitationId), {
...invitationData,
updatedAt: new Date()
});
return invitationId;
}
catch (error) {
console.error('Error updating invitation:', error);
throw error;
}
};
export const deleteInvitation = async (invitationId) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
await deleteDoc(doc(currentDb, 'invitations', invitationId));
return invitationId;
}
catch (error) {
console.error('Error deleting invitation:', error);
throw error;
}
};
// Helper function to generate a random token
const generateInvitationToken = () => {
return Math.random().toString(36).substring(2, 15) +
Math.random().toString(36).substring(2, 15);
};
// Get user by email
export const getUserByEmail = async (email) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
const usersRef = collection(currentDb, 'users');
const q = query(usersRef, where('email', '==', email));
const snapshot = await getDocs(q);
if (snapshot.empty) {
return null;
}
const userDoc = snapshot.docs[0];
return { uid: userDoc.id, ...userDoc.data() };
}
catch (error) {
console.error('Error getting user by email:', error);
throw error;
}
};
// Get invitations by email
export const getInvitationsByEmail = async (email) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
const invitationsRef = collection(currentDb, 'invitations');
const q = query(invitationsRef, where('email', '==', email));
const snapshot = await getDocs(q);
return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
}
catch (error) {
console.error('Error getting invitations by email:', error);
throw error;
}
};
// Get invitations by organization
export const getInvitationsByOrg = async (orgId) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
const invitationsRef = collection(currentDb, 'invitations');
const q = query(invitationsRef, where('orgId', '==', orgId));
const snapshot = await getDocs(q);
return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
}
catch (error) {
console.error('Error getting invitations by organization:', error);
throw error;
}
};
// Update invitation status
export const updateInvitationStatus = async (invitationId, status) => {
console.log('[Firestore Service] Updating invitation status:', { invitationId, status });
// Get a fresh reference to Firestore
const currentDb = getFirestore();
if (!currentDb) {
console.error('[Firestore Service] Firestore not initialized in updateInvitationStatus');
throw new Error('Firestore not initialized');
}
try {
const invitationRef = doc(currentDb, 'invitations', invitationId);
await updateDoc(invitationRef, { status });
}
catch (error) {
console.error('[Firestore Service] Error updating invitation status:', error);
throw error;
}
};
// Cancel invitation
export const cancelInvitation = async (invitationId) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
await deleteDoc(doc(currentDb, 'invitations', invitationId));
}
catch (error) {
console.error('Error canceling invitation:', error);
throw error;
}
};
// Accept invitation
export const acceptInvitation = async (invitationId, userId) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
// Get the invitation
const invitationRef = doc(currentDb, 'invitations', invitationId);
const invitationDoc = await getDoc(invitationRef);
if (!invitationDoc.exists()) {
throw new Error('Invitation not found');
}
const invitation = invitationDoc.data();
if (invitation.status !== 'pending') {
throw new Error('Invitation is no longer pending');
}
// Update invitation status
await updateDoc(invitationRef, {
status: 'accepted',
updatedAt: new Date()
});
// Add user to organization
await addUserToOrganization(invitation.orgId, userId, invitation.role);
}
catch (error) {
console.error('Error accepting invitation:', error);
throw error;
}
};
// Decline invitation
export const declineInvitation = async (invitationId) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
// Get the invitation
const invitationRef = doc(currentDb, 'invitations', invitationId);
const invitationDoc = await getDoc(invitationRef);
if (!invitationDoc.exists()) {
throw new Error('Invitation not found');
}
// Update invitation status
await updateDoc(invitationRef, {
status: 'declined',
updatedAt: new Date()
});
}
catch (error) {
console.error('Error declining invitation:', error);
throw error;
}
};
// Resend invitation
export const resendInvitation = async (invitationId, callbacks) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
// Get the invitation
const invitationRef = doc(currentDb, 'invitations', invitationId);
const invitationDoc = await getDoc(invitationRef);
if (!invitationDoc.exists()) {
throw new Error('Invitation not found');
}
const invitation = invitationDoc.data();
// Generate a new token and update expiration
const token = generateInvitationToken();
const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
// Update the invitation
const updatedInvitation = {
...invitation,
token,
expiresAt,
updatedAt: new Date()
};
await updateDoc(invitationRef, updatedInvitation);
// Create result object with id
const result = {
...updatedInvitation,
id: invitationId
};
// Call the callback if provided
if (callbacks?.onInvitationResent) {
callbacks.onInvitationResent(result);
}
return result;
}
catch (error) {
console.error('Error resending invitation:', error);
throw error;
}
};
// Create a new session
export const createSession = async (userId) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
// Get device info if available
let deviceInfo = {};
if (typeof window !== 'undefined') {
deviceInfo = {
userAgent: window.navigator.userAgent,
platform: window.navigator.platform,
language: window.navigator.language
};
}
// Create session with auto-generated ID
const sessionRef = doc(collection(currentDb, 'sessions'));
const sessionId = sessionRef.id;
const sessionData = {
id: sessionId,
userId,
deviceInfo: JSON.stringify(deviceInfo),
lastActive: new Date(),
createdAt: new Date(),
// Default session expiration: 30 days
expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)
};
await setDoc(sessionRef, sessionData);
// Store session ID in localStorage if available
if (typeof window !== 'undefined' && window.localStorage) {
localStorage.setItem('sessionId', sessionId);
}
return sessionId;
}
catch (error) {
console.error('Error creating session:', error);
throw error;
}
};
// Update session activity
export const updateSessionActivity = async (sessionId) => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
const sessionRef = doc(currentDb, 'sessions', sessionId);
await updateDoc(sessionRef, {
lastActive: new Date()
});
}
catch (error) {
console.error('Error updating session activity:', error);
throw error;
}
};
// Get user sessions
export const getUserSessions = async (userId) => {
console.log('[Firestore Service] Getting user sessions for:', userId);
// Get a fresh reference to Firestore
const currentDb = getFirestore();
if (!currentDb) {
console.error('[Firestore Service] Firestore not initialized in getUserSessions');
throw new Error('Firestore not initialized');
}
console.log('[Firestore Service] Firestore instance obtained, querying sessions');
try {
const sessionsQuery = query(collection(currentDb, 'sessions'), where('userId', '==', userId));
const sessionsSnapshot = await getDocs(sessionsQuery);
const sessions = [];
sessionsSnapshot.forEach(doc => {
const data = doc.data();
// Safely handle date fields
const lastActive = data.lastActive ? data.lastActive : new Date();
const createdAt = data.createdAt ? data.createdAt : new Date();
const expiresAt = data.expiresAt || null;
sessions.push({
id: doc.id,
userId: data.userId,
deviceInfo: data.deviceInfo || 'Unknown device',
ipAddress: data.ipAddress,
location: data.location,
lastActive,
createdAt,
expiresAt
});
});
console.log('[Firestore Service] Retrieved sessions:', sessions.length);
return sessions;
}
catch (error) {
console.error('[Firestore Service] Error getting user sessions:', error);
throw error;
}
};
// Terminate a session
export const terminateSession = async (sessionId) => {
console.log('[Firestore Service] Terminating session:', sessionId);
// Get a fresh reference to Firestore
const currentDb = getFirestore();
if (!currentDb) {
console.error('[Firestore Service] Firestore not initialized in terminateSession');
throw new Error('Firestore not initialized');
}
console.log('[Firestore Service] Firestore instance obtained, deleting session');
try {
const sessionRef = doc(currentDb, 'sessions', sessionId);
await deleteDoc(sessionRef);
console.log('[Firestore Service] Session terminated successfully');
}
catch (error) {
console.error('[Firestore Service] Error terminating session:', error);
throw error;
}
};
// Validate current session
export const validateSession = async () => {
try {
const currentDb = getFirestore();
if (!currentDb)
throw new Error('Firestore not initialized');
const sessionId = localStorage.getItem('sessionId');
if (!sessionId) {
return false;
}
const sessionRef = doc(currentDb, 'sessions', sessionId);
const sessionDoc = await getDoc(sessionRef);
if (!sessionDoc.exists()) {
return false;
}
const session = sessionDoc.data();
const now = new Date();
// Check if session has expired
if (session.expiresAt && new Date(session.expiresAt) < now) {
await deleteDoc(sessionRef);
localStorage.removeItem('sessionId');
return false;
}
// Update last active timestamp
await updateDoc(sessionRef, {
lastActive: now
});
return true;
}
catch (error) {
console.error('Error validating session:', error);
return false;
}
};
// Clear the current session
export const clearSession = async () => {
console.log('[Firestore Service] Clearing session');
try {
// Get session ID from local storage
const sessionId = localStorage.getItem('sessionId');
if (sessionId) {
// Get a fresh reference to Firestore
const currentDb = getFirestore();
if (currentDb) {
await deleteDoc(doc(currentDb, 'sessions', sessionId));
}
// Clear session ID from local storage
localStorage.removeItem('sessionId');
}
}
catch (error) {
console.error('[Firestore Service] Error clearing session:', error);
// Don't throw error here, just log it
}
};
//# sourceMappingURL=firestore.js.map