Rework backend #1
+18
-39
@@ -1,7 +1,7 @@
|
||||
import React, { useState, useEffect, useRef, useMemo } from 'react';
|
||||
import { initializeApp } from './storage';
|
||||
import { getAuth, signInAnonymously, onAuthStateChanged, signInWithCustomToken } from './storage';
|
||||
import { getFirestore, doc, setDoc, getDoc, getDocs, addDoc, collection, onSnapshot, updateDoc, deleteDoc, query, orderBy, limit, writeBatch } from './storage';
|
||||
import { getFirestore, doc, setDoc, getDoc, getDocs, addDoc, collection, onSnapshot, updateDoc, deleteDoc, query, orderBy, limit, writeBatch, getStorage } from './storage';
|
||||
import {
|
||||
PlusCircle, Users, Swords, Trash2, Eye, Edit3, Save, XCircle, ChevronsUpDown,
|
||||
UserCheck, UserX, HeartCrack, HeartPulse, Zap, EyeOff, ExternalLink, AlertTriangle,
|
||||
@@ -201,32 +201,22 @@ function useFirestoreDocument(docPath) {
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!db || !docPath) {
|
||||
if (!docPath) {
|
||||
setData(null);
|
||||
setIsLoading(false);
|
||||
setError(docPath ? "Firestore not available." : "Document path not provided.");
|
||||
setError("Document path not provided.");
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
|
||||
const docRef = doc(db, docPath);
|
||||
const unsubscribe = onSnapshot(
|
||||
docRef,
|
||||
(docSnap) => {
|
||||
setData(docSnap.exists() ? { id: docSnap.id, ...docSnap.data() } : null);
|
||||
setIsLoading(false);
|
||||
},
|
||||
(err) => {
|
||||
console.error(`Error fetching document ${docPath}:`, err);
|
||||
setError(err.message || "Failed to fetch document.");
|
||||
setIsLoading(false);
|
||||
setData(null);
|
||||
}
|
||||
);
|
||||
|
||||
return () => unsubscribe();
|
||||
const storage = getStorage();
|
||||
const unsubscribe = storage.subscribeDoc(docPath, (doc) => {
|
||||
setData(doc);
|
||||
setIsLoading(false);
|
||||
});
|
||||
return () => { if (typeof unsubscribe === 'function') unsubscribe(); };
|
||||
}, [docPath]);
|
||||
|
||||
return { data, isLoading, error };
|
||||
@@ -239,34 +229,23 @@ function useFirestoreCollection(collectionPath, queryConstraints = []) {
|
||||
const queryString = useMemo(() => JSON.stringify(queryConstraints), [queryConstraints]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!db || !collectionPath) {
|
||||
if (!collectionPath) {
|
||||
setData([]);
|
||||
setIsLoading(false);
|
||||
setError(collectionPath ? "Firestore not available." : "Collection path not provided.");
|
||||
setError("Collection path not provided.");
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
|
||||
const q = query(collection(db, collectionPath), ...queryConstraints);
|
||||
const unsubscribe = onSnapshot(
|
||||
q,
|
||||
(snapshot) => {
|
||||
const items = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
|
||||
setData(items);
|
||||
setIsLoading(false);
|
||||
},
|
||||
(err) => {
|
||||
console.error(`Error fetching collection ${collectionPath}:`, err);
|
||||
setError(err.message || "Failed to fetch collection.");
|
||||
setIsLoading(false);
|
||||
setData([]);
|
||||
}
|
||||
);
|
||||
|
||||
return () => unsubscribe();
|
||||
// We use queryString instead of queryConstraints to avoid re-renders on array reference changes
|
||||
const storage = getStorage();
|
||||
const unsubscribe = storage.subscribeCollection(collectionPath, (items) => {
|
||||
setData(items);
|
||||
setIsLoading(false);
|
||||
});
|
||||
return () => { if (typeof unsubscribe === 'function') unsubscribe(); };
|
||||
// queryString, not array ref
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [collectionPath, queryString]);
|
||||
|
||||
|
||||
+41
-7
@@ -1,13 +1,47 @@
|
||||
// src/storage/index.js — barrel re-export of Firebase SDK.
|
||||
// Phase C: App.js swaps imports from 'firebase/*' to here.
|
||||
// STORAGE=firebase = identical behavior. Zero risk.
|
||||
// Later: factory picks impl based on REACT_APP_STORAGE env.
|
||||
// src/storage/index.js — storage factory + SDK re-exports.
|
||||
// STORAGE=firebase (default): adapter wraps SDK. STORAGE=ws: backend.
|
||||
// App.js imports getStorage() for subscribe; still imports SDK pieces for writes (per-group refactor pending).
|
||||
|
||||
export { initializeApp } from 'firebase/app';
|
||||
export {
|
||||
import { initializeApp } from 'firebase/app';
|
||||
import {
|
||||
getAuth, signInAnonymously, onAuthStateChanged, signInWithCustomToken,
|
||||
} from 'firebase/auth';
|
||||
export {
|
||||
import {
|
||||
getFirestore, doc, setDoc, getDoc, getDocs, addDoc, collection,
|
||||
onSnapshot, updateDoc, deleteDoc, query, orderBy, limit, writeBatch,
|
||||
} from 'firebase/firestore';
|
||||
import { initFirebase, createFirebaseStorage } from './firebase';
|
||||
|
||||
let storageInstance = null;
|
||||
|
||||
// Returns adapter instance implementing interface (getDoc/setDoc/subscribeDoc/etc).
|
||||
export function getStorage() {
|
||||
if (storageInstance) return storageInstance;
|
||||
const mode = process.env.REACT_APP_STORAGE || 'firebase';
|
||||
if (mode === 'firebase') {
|
||||
const ok = initFirebase();
|
||||
if (!ok) throw new Error('Firebase config missing. Check REACT_APP_FIREBASE_* env.');
|
||||
storageInstance = createFirebaseStorage();
|
||||
} else if (mode === 'ws') {
|
||||
const { createWsStorage } = require('./ws');
|
||||
storageInstance = createWsStorage({
|
||||
baseUrl: process.env.REACT_APP_BACKEND_URL || 'http://127.0.0.1:4001',
|
||||
wsUrl: process.env.REACT_APP_BACKEND_WS || 'ws://127.0.0.1:4001/ws',
|
||||
});
|
||||
} else {
|
||||
const { createMemoryStorage } = require('./memory');
|
||||
storageInstance = createMemoryStorage();
|
||||
}
|
||||
return storageInstance;
|
||||
}
|
||||
|
||||
export function getStorageMode() {
|
||||
return process.env.REACT_APP_STORAGE || 'firebase';
|
||||
}
|
||||
|
||||
export {
|
||||
initializeApp,
|
||||
getAuth, signInAnonymously, onAuthStateChanged, signInWithCustomToken,
|
||||
getFirestore, doc, setDoc, getDoc, getDocs, addDoc, collection,
|
||||
onSnapshot, updateDoc, deleteDoc, query, orderBy, limit, writeBatch,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user