Gathering detailed insights and metrics for akshay-khapare-expo-firebase-hooks
Gathering detailed insights and metrics for akshay-khapare-expo-firebase-hooks
Gathering detailed insights and metrics for akshay-khapare-expo-firebase-hooks
Gathering detailed insights and metrics for akshay-khapare-expo-firebase-hooks
npm install akshay-khapare-expo-firebase-hooks
Typescript
Module System
Min. Node Version
Node Version
NPM Version
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
3
22
Production-ready Firebase hooks for Expo React Native applications with comprehensive error handling and TypeScript support.
1npm install akshay-khapare-expo-firebase-hooks
1npm install react react-native firebase
Initialize Firebase once in your app:
1import { firebaseInit } from 'akshay-khapare-expo-firebase-hooks'; 2 3firebaseInit({ 4 projects: [ 5 { 6 projectName: 'main-project', 7 config: { 8 apiKey: 'your-api-key', 9 authDomain: 'your-project.firebaseapp.com', 10 projectId: 'your-project-id', 11 storageBucket: 'your-project.appspot.com', 12 messagingSenderId: '123456789', 13 appId: '1:123456789:web:abcdef123456', 14 }, 15 }, 16 ], 17});
1interface User { 2 id: string; 3 name: string; 4 email: string; 5 status: 'online' | 'offline'; 6} 7 8function MyComponent() { 9 const { getDocument } = useFirestoreGetDoc(); 10 const { addDocument } = useFirestoreAdd(); 11 const [loading, setLoading] = useState(false); 12 13 const handleGetUser = async () => { 14 try { 15 setLoading(true); 16 const user = await getDocument<User>({ 17 projectName: 'main-project', 18 collectionName: 'users', 19 documentId: 'user123', 20 }); 21 console.log('User:', user?.name); 22 } catch (error) { 23 console.error('Error:', error.message); 24 } finally { 25 setLoading(false); 26 } 27 }; 28 29 const handleAddUser = async () => { 30 try { 31 const result = await addDocument({ 32 projectName: 'main-project', 33 collectionName: 'users', 34 data: { name: 'John', email: 'john@example.com' }, 35 }); 36 console.log('Added user with ID:', result.id); 37 Alert.alert('Success', `User created with ID: ${result.id}`); 38 } catch (error) { 39 if (error.code === FirebaseErrorCode.PERMISSION_DENIED) { 40 Alert.alert('Permission Error', 'You do not have permission to add users.'); 41 } else { 42 Alert.alert('Error', 'Failed to add user: ' + error.message); 43 } 44 } finally { 45 setLoading(false); 46 } 47 }; 48 49 return ( 50 <View> 51 <Button title="Get User" onPress={handleGetUser} /> 52 <Button title="Add User" onPress={handleAddUser} /> 53 </View> 54 ); 55}
Add documents to any Firestore collection. Returns the document ID directly.
Parameters:
projectName
: string - Firebase project identifiercollectionName
: string - Firestore collection namedata
: Record<string, unknown> - Document data to addReturns: Promise<{ id: string }>
- The newly created document ID
Throws: FirebaseHookError
- For any Firebase operation errors
Potential Errors:
collectionName
or data
are invalid.1import { useFirestoreAdd, FirebaseErrorCode } from 'akshay-khapare-expo-firebase-hooks'; 2 3function AddUserComponent() { 4 const { addDocument } = useFirestoreAdd(); 5 const [loading, setLoading] = useState(false); 6 7 const handleAddUser = async () => { 8 try { 9 setLoading(true); 10 const result = await addDocument({ 11 projectName: 'main-project', 12 collectionName: 'users', 13 data: { 14 name: 'John', 15 email: 'john@example.com', 16 status: 'online', 17 createdAt: new Date().toISOString(), 18 }, 19 }); 20 21 console.log('User added with ID:', result.id); 22 Alert.alert('Success', `User created with ID: ${result.id}`); 23 } catch (error) { 24 if (error.code === FirebaseErrorCode.PERMISSION_DENIED) { 25 Alert.alert('Permission Error', 'You do not have permission to add users.'); 26 } else { 27 Alert.alert('Error', 'Failed to add user: ' + error.message); 28 } 29 } finally { 30 setLoading(false); 31 } 32 }; 33 34 return ( 35 <TouchableOpacity onPress={handleAddUser} disabled={loading}> 36 <Text>{loading ? 'Adding...' : 'Add User'}</Text> 37 </TouchableOpacity> 38 ); 39}
Error Handling:
Set documents with specific IDs (creates or overwrites). No return value.
Parameters:
projectName
: string - Firebase project identifiercollectionName
: string - Firestore collection namedocumentId
: string - Document ID to setdata
: Record<string, unknown> - Document datamerge
: boolean (optional) - Whether to merge with existing data (default: false)Returns: Promise<void>
Throws: FirebaseHookError
- For any Firebase operation errors
Potential Errors:
collectionName
, documentId
, or data
are invalid (INVALID_ARGUMENT
).PERMISSION_DENIED
).NETWORK_ERROR
).1import { useFirestoreSet, FirebaseErrorCode } from 'akshay-khapare-expo-firebase-hooks'; 2 3function SetUserComponent() { 4 const { setDocument } = useFirestoreSet(); 5 const [isUpdating, setIsUpdating] = useState(false); 6 7 const handleSetUser = async () => { 8 try { 9 setIsUpdating(true); 10 await setDocument({ 11 projectName: 'main-project', 12 collectionName: 'users', 13 documentId: 'user123', 14 data: { 15 name: 'John Updated', 16 email: 'john.updated@example.com', 17 updatedAt: new Date().toISOString(), 18 }, 19 merge: true, // Merge with existing data 20 }); 21 22 Alert.alert('Success', 'User updated successfully!'); 23 } catch (error) { 24 if (error.code === FirebaseErrorCode.PERMISSION_DENIED) { 25 Alert.alert('Permission Error', 'You are not allowed to edit this user.'); 26 } else { 27 Alert.alert('Error', 'Failed to update user: ' + error.message); 28 } 29 } finally { 30 setIsUpdating(false); 31 } 32 }; 33 34 return ( 35 <Button 36 title={isUpdating ? "Updating..." : "Set User"} 37 onPress={handleSetUser} 38 disabled={isUpdating} 39 /> 40 ); 41}
Update existing documents. Only updates specified fields.
Parameters:
projectName
: string - Firebase project identifiercollectionName
: string - Firestore collection namedocumentId
: string - Document ID to updatedata
: Record<string, unknown> - Fields to updateReturns: Promise<void>
Throws: FirebaseHookError
- For any Firebase operation errors
Potential Errors:
DOCUMENT_NOT_FOUND
).collectionName
, documentId
, or data
are invalid (INVALID_ARGUMENT
).PERMISSION_DENIED
).NETWORK_ERROR
).1import { useFirestoreUpdate, FirebaseErrorCode } from 'akshay-khapare-expo-firebase-hooks'; 2 3function UpdateUserComponent() { 4 const { updateDocument } = useFirestoreUpdate(); 5 const [loading, setLoading] = useState(false); 6 7 const handleUpdateUserStatus = async (status: 'online' | 'offline') => { 8 try { 9 setLoading(true); 10 await updateDocument({ 11 projectName: 'main-project', 12 collectionName: 'users', 13 documentId: 'user123', 14 data: { 15 status, 16 lastSeen: new Date().toISOString(), 17 }, 18 }); 19 20 console.log('User status updated to:', status); 21 } catch (error) { 22 if (error.code === FirebaseErrorCode.DOCUMENT_NOT_FOUND) { 23 Alert.alert('Not Found', 'This user does not exist and cannot be updated.'); 24 } else { 25 Alert.alert('Update Error', error.message); 26 } 27 } finally { 28 setLoading(false); 29 } 30 }; 31 32 return ( 33 <View> 34 <Button 35 title="Set Online" 36 onPress={() => handleUpdateUserStatus('online')} 37 disabled={loading} 38 /> 39 <Button 40 title="Set Offline" 41 onPress={() => handleUpdateUserStatus('offline')} 42 disabled={loading} 43 /> 44 </View> 45 ); 46}
Delete documents from Firestore permanently.
Parameters:
projectName
: string - Firebase project identifiercollectionName
: string - Firestore collection namedocumentId
: string - Document ID to deleteReturns: Promise<void>
Throws: FirebaseHookError
- For any Firebase operation errors
Potential Errors:
collectionName
or documentId
are invalid (INVALID_ARGUMENT
).PERMISSION_DENIED
).NETWORK_ERROR
).1import { useFirestoreDelete, FirebaseErrorCode } from 'akshay-khapare-expo-firebase-hooks'; 2 3function DeleteUserComponent() { 4 const { deleteDocument } = useFirestoreDelete(); 5 const [deleting, setDeleting] = useState(false); 6 7 const handleDeleteUser = async (userId: string) => { 8 try { 9 // Confirm deletion 10 Alert.alert( 11 'Confirm Delete', 12 'Are you sure you want to delete this user?', 13 [ 14 { text: 'Cancel', style: 'cancel' }, 15 { 16 text: 'Delete', 17 style: 'destructive', 18 onPress: async () => { 19 try { 20 setDeleting(true); 21 await deleteDocument({ 22 projectName: 'main-project', 23 collectionName: 'users', 24 documentId: userId, 25 }); 26 27 Alert.alert('Success', 'User deleted successfully'); 28 } catch (error) { 29 if (error.code === FirebaseErrorCode.PERMISSION_DENIED) { 30 Alert.alert('Permission Error', 'You do not have permission to delete this user.'); 31 } else { 32 Alert.alert('Delete Error', error.message); 33 } 34 } finally { 35 setDeleting(false); 36 } 37 } 38 } 39 ] 40 ); 41 } catch (error) { 42 console.error('Delete failed:', error.message); 43 } 44 }; 45 46 return ( 47 <Button 48 title={deleting ? "Deleting..." : "Delete User"} 49 onPress={() => handleDeleteUser('user123')} 50 disabled={deleting} 51 color="red" 52 /> 53 ); 54}
Fetch a single document from Firestore. Returns the document data or null if not found.
Parameters:
projectName
: string - Firebase project identifiercollectionName
: string - Firestore collection namedocumentId
: string - Document ID to fetchReturns: Promise<T | null>
- Document data with ID field added, or null if not found
Throws: FirebaseHookError
- For any Firebase operation errors
Potential Errors:
collectionName
or documentId
are invalid (INVALID_ARGUMENT
).PERMISSION_DENIED
).NETWORK_ERROR
).1import { useFirestoreGetDoc, FirebaseErrorCode } from 'akshay-khapare-expo-firebase-hooks'; 2 3interface User { 4 id: string; 5 name: string; 6 email: string; 7 status: 'online' | 'offline'; 8} 9 10function GetUserComponent() { 11 const { getDocument } = useFirestoreGetDoc(); 12 const [user, setUser] = useState<User | null>(null); 13 const [loading, setLoading] = useState(false); 14 15 const fetchUser = async (userId: string) => { 16 try { 17 setLoading(true); 18 const userData = await getDocument<User>({ 19 projectName: 'main-project', 20 collectionName: 'users', 21 documentId: userId, 22 }); 23 24 if (userData) { 25 console.log('Found user:', userData.name); 26 setUser(userData); 27 } else { 28 console.log('User not found'); 29 Alert.alert('Not Found', 'User does not exist'); 30 } 31 } catch (error) { 32 if (error.code === FirebaseErrorCode.PERMISSION_DENIED) { 33 Alert.alert('Permission Error', 'You do not have access to this user\'s data.'); 34 } else { 35 Alert.alert('Error', 'Failed to fetch user: ' + error.message); 36 } 37 } finally { 38 setLoading(false); 39 } 40 }; 41 42 return ( 43 <View> 44 <Button 45 title={loading ? "Loading..." : "Fetch User"} 46 onPress={() => fetchUser('user123')} 47 disabled={loading} 48 /> 49 {user && ( 50 <View> 51 <Text>Name: {user.name}</Text> 52 <Text>Email: {user.email}</Text> 53 <Text>Status: {user.status}</Text> 54 </View> 55 )} 56 </View> 57 ); 58}
Fetch multiple documents from a collection with optional query constraints.
Parameters:
projectName
: string - Firebase project identifiercollectionName
: string - Firestore collection namequeries
: QueryConstraint[] (optional) - Firestore query constraintsReturns: Promise<T[]>
- Array of documents with ID fields added
Throws: FirebaseHookError
- For any Firebase operation errors
Potential Errors:
collectionName
is invalid (INVALID_ARGUMENT
).queries
is malformed (e.g., incorrect field path or operator) (INVALID_ARGUMENT
).PERMISSION_DENIED
).NETWORK_ERROR
).1import { useFirestoreGetCollection, FirebaseErrorCode } from 'akshay-khapare-expo-firebase-hooks'; 2import { where, orderBy, limit } from 'firebase/firestore'; 3 4interface User { 5 id: string; 6 name: string; 7 email: string; 8 status: 'online' | 'offline'; 9 createdAt: string; 10} 11 12function GetUsersComponent() { 13 const { getCollection } = useFirestoreGetCollection(); 14 const [users, setUsers] = useState<User[]>([]); 15 const [loading, setLoading] = useState(false); 16 17 const fetchOnlineUsers = async () => { 18 try { 19 setLoading(true); 20 const userData = await getCollection<User>({ 21 projectName: 'main-project', 22 collectionName: 'users', 23 queries: [ 24 where('status', '==', 'online'), 25 orderBy('createdAt', 'desc'), 26 limit(10) 27 ], 28 }); 29 30 console.log('Found', userData.length, 'online users'); 31 setUsers(userData); 32 } catch (error) { 33 if (error.code === FirebaseErrorCode.INVALID_ARGUMENT) { 34 Alert.alert('Query Error', 'There is an issue with the query constraints.'); 35 } else { 36 Alert.alert('Error', 'Failed to fetch users: ' + error.message); 37 } 38 } finally { 39 setLoading(false); 40 } 41 }; 42 43 const fetchAllUsers = async () => { 44 try { 45 setLoading(true); 46 const userData = await getCollection<User>({ 47 projectName: 'main-project', 48 collectionName: 'users', 49 // No queries = fetch all documents 50 }); 51 52 setUsers(userData); 53 } catch (error) { 54 console.error('Fetch failed:', error.message); 55 } finally { 56 setLoading(false); 57 } 58 }; 59 60 return ( 61 <View> 62 <Button title="Fetch Online Users" onPress={fetchOnlineUsers} /> 63 <Button title="Fetch All Users" onPress={fetchAllUsers} /> 64 65 {loading && <Text>Loading...</Text>} 66 67 <FlatList 68 data={users} 69 keyExtractor={(item) => item.id} 70 renderItem={({ item }) => ( 71 <View> 72 <Text>{item.name} - {item.status}</Text> 73 </View> 74 )} 75 /> 76 </View> 77 ); 78}
Check if a document exists without fetching its data.
Parameters:
projectName
: string - Firebase project identifiercollectionName
: string - Firestore collection namedocumentId
: string - Document ID to checkReturns: Promise<boolean>
- true if document exists, false otherwise
Throws: FirebaseHookError
- For any Firebase operation errors
Potential Errors:
collectionName
or documentId
are invalid (INVALID_ARGUMENT
).PERMISSION_DENIED
).NETWORK_ERROR
).1import { useFirestoreDocumentExists, FirebaseErrorCode } from 'akshay-khapare-expo-firebase-hooks'; 2 3function CheckUserComponent() { 4 const { checkDocumentExists } = useFirestoreDocumentExists(); 5 const [checking, setChecking] = useState(false); 6 7 const checkUserExists = async (userId: string) => { 8 try { 9 setChecking(true); 10 const exists = await checkDocumentExists({ 11 projectName: 'main-project', 12 collectionName: 'users', 13 documentId: userId, 14 }); 15 16 if (exists) { 17 Alert.alert('Found', 'User exists in database'); 18 } else { 19 Alert.alert('Not Found', 'User does not exist'); 20 } 21 } catch (error) { 22 if (error.code === FirebaseErrorCode.PERMISSION_DENIED) { 23 Alert.alert('Permission Error', 'You do not have permission to check this user.'); 24 } else { 25 Alert.alert('Error', 'Failed to check user: ' + error.message); 26 } 27 } finally { 28 setChecking(false); 29 } 30 }; 31 32 return ( 33 <Button 34 title={checking ? "Checking..." : "Check User Exists"} 35 onPress={() => checkUserExists('user123')} 36 disabled={checking} 37 /> 38 ); 39}
Listens for real-time updates to a single document in a Firestore collection. The hook manages the subscription lifecycle and automatically unsubscribes on unmount.
DocumentListenerParams<T>
: An object containing:
projectName
(string): The Firebase project name.collectionName
(string): The name of the collection.documentId
(string): The ID of the document to listen to.onSuccess
((data: T | null) => void): Callback for successful updates. Receives the document data (with id
) or null
if it doesn't exist.onError
((error: FirebaseHookError) => void): Callback for handling errors.unsubscribe
(function): A function that can be called to manually stop the listener.onError
callback)collectionName
or documentId
(INVALID_ARGUMENT
).PERMISSION_DENIED
).NETWORK_ERROR
).1import React, { useState, useEffect } from 'react';
2import {
3 useFirestoreDocumentListener,
4 FirebaseErrorCode,
5} from 'akshay-khapare-expo-firebase-hooks';
6
7const UserProfile = ({ userId }) => {
8 const [user, setUser] = useState(null);
9 const [error, setError] = useState(null);
10
11 const unsubscribe = useFirestoreDocumentListener({
12 projectName: 'my-project',
13 collectionName: 'users',
14 documentId: userId,
15 onSuccess: data => {
16 console.log('Received real-time update:', data);
17 setUser(data);
18 },
19 onError: err => {
20 console.error('Listener Error:', err);
21 if (err.code === FirebaseErrorCode.PERMISSION_DENIED) {
22 setError('You do not have permission to view this profile.');
23 } else {
24 setError(err.message);
25 }
26 },
27 });
28
29 // You can manually unsubscribe if needed, e.g., on a button click
30 // useEffect(() => {
31 // return () => unsubscribe();
32 // }, [unsubscribe]);
33
34 if (error) {
35 return <p>Error: {error}</p>;
36 }
37
38 return (
39 <div>
40 <h2>User Profile (Real-time)</h2>
41 {user ? (
42 <pre>{JSON.stringify(user, null, 2)}</pre>
43 ) : (
44 <p>Loading user...</p>
45 )}
46 </div>
47 );
48};
Listens for real-time updates to a collection in Firestore, with optional queries. The hook manages the subscription lifecycle and automatically unsubscribes on unmount.
CollectionListenerParams<T>
: An object containing:
projectName
(string): The Firebase project name.collectionName
(string): The name of the collection.queries
(QueryConstraint[] - optional): An array of Firestore queries (where
, orderBy
, limit
).onSuccess
((data: T[]) => void): Callback for successful updates. Receives an array of document data (with id
).onError
((error: FirebaseHookError) => void): Callback for handling errors.unsubscribe
(function): A function that can be called to manually stop the listener.onError
callback)collectionName
(INVALID_ARGUMENT
).INVALID_ARGUMENT
).PERMISSION_DENIED
).NETWORK_ERROR
).1import React, { useState, useEffect } from 'react'; 2import { 3 useFirestoreCollectionListener, 4 FirebaseErrorCode, 5} from 'akshay-khapare-expo-firebase-hooks'; 6import { where, orderBy } from 'firebase/firestore'; 7 8const ActiveUsersList = () => { 9 const [users, setUsers] = useState([]); 10 const [error, setError] = useState(null); 11 12 const unsubscribe = useFirestoreCollectionListener({ 13 projectName: 'my-project', 14 collectionName: 'users', 15 queries: [where('status', '==', 'active'), orderBy('lastSeen', 'desc')], 16 onSuccess: data => { 17 console.log('Received real-time collection update:', data); 18 setUsers(data); 19 }, 20 onError: err => { 21 console.error('Listener Error:', err); 22 if (err.code === FirebaseErrorCode.PERMISSION_DENIED) { 23 setError('You do not have permission to view this list of users.'); 24 } else if (err.code === FirebaseErrorCode.INVALID_ARGUMENT) { 25 setError('The query is invalid. Please check the constraints.'); 26 } else { 27 setError(err.message); 28 } 29 }, 30 }); 31 32 if (error) { 33 return <p>Error: {error}</p>; 34 } 35 36 return ( 37 <div> 38 <h2>Active Users (Real-time)</h2> 39 <ul> 40 {users.map(user => ( 41 <li key={user.id}>{user.name}</li> 42 ))} 43 </ul> 44 </div> 45 ); 46};
Execute multiple Firestore operations in a single atomic transaction.
Parameters:
operations
: BatchOperation[] - Array of operations to executeReturns: Promise<void>
Throws: FirebaseHookError
- For any Firebase operation errors
Potential Errors:
operations
array is empty or an operation object is missing required fields (type
, collectionName
, etc.) (INVALID_ARGUMENT
).INVALID_ARGUMENT
).PERMISSION_DENIED
).NETWORK_ERROR
).1import { useFirestoreTransaction, FirebaseErrorCode } from 'akshay-khapare-expo-firebase-hooks'; 2 3function BatchOperationsComponent() { 4 const { executeBatch } = useFirestoreTransaction(); 5 const [processing, setProcessing] = useState(false); 6 7 const performBatchOperations = async () => { 8 try { 9 setProcessing(true); 10 11 await executeBatch({ 12 operations: [ 13 { 14 type: 'set', 15 projectName: 'main-project', 16 collectionName: 'users', 17 documentId: 'user1', 18 data: { name: 'John', status: 'online' }, 19 merge: true, 20 }, 21 { 22 type: 'update', 23 projectName: 'main-project', 24 collectionName: 'users', 25 documentId: 'user2', 26 data: { lastSeen: new Date().toISOString() }, 27 }, 28 { 29 type: 'delete', 30 projectName: 'main-project', 31 collectionName: 'users', 32 documentId: 'user3', 33 }, 34 ], 35 }); 36 37 Alert.alert('Success', 'Batch operations completed!'); 38 } catch (error) { 39 if (error.code === FirebaseErrorCode.INVALID_ARGUMENT) { 40 Alert.alert('Invalid Operation', error.message); 41 } else if (error.code === FirebaseErrorCode.PERMISSION_DENIED) { 42 Alert.alert('Permission Denied', 'You do not have permission for one of the operations in the batch.'); 43 } else { 44 Alert.alert('Batch Error', error.message); 45 } 46 } finally { 47 setProcessing(false); 48 } 49 }; 50 51 return ( 52 <Button 53 title={processing ? "Processing..." : "Execute Batch"} 54 onPress={performBatchOperations} 55 disabled={processing} 56 /> 57 ); 58}
All hooks use comprehensive error handling that covers:
All thrown errors are instances of FirebaseHookError
and will have a code
property that corresponds to the FirebaseErrorCode
enum. You should import and use this enum for type-safe error checking.
FirebaseErrorCode.INVALID_ARGUMENT
: Missing or invalid parameters passed to a hook.FirebaseErrorCode.PERMISSION_DENIED
: User does not have permission according to Firestore security rules.FirebaseErrorCode.NETWORK_ERROR
: The device is offline or the connection is unstable.FirebaseErrorCode.DOCUMENT_NOT_FOUND
: A document specified for an update or delete operation does not exist.FirebaseErrorCode.OPERATION_FAILED
: A generic failure from the Firebase SDK.FirebaseErrorCode.UNKNOWN_ERROR
: An unexpected error occurred.1import { FirebaseErrorCode } from 'akshay-khapare-expo-firebase-hooks'; 2interface FirebaseHookError extends Error { 3 message: string; // Human-readable error message 4 code?: string; // Firebase error code 5 originalError?: Error; // Original Firebase error object 6}
1try { 2 const result = await addDocument({ ... }); 3 // Handle success 4} catch (error) { 5 // Handle error 6 console.error('Operation failed:', error.message); 7}
1catch (error) { 2 if (error.code === FirebaseErrorCode.PERMISSION_DENIED) { 3 Alert.alert('Access Denied', 'You don\'t have permission for this action'); 4 } else if (error.code === FirebaseErrorCode.DOCUMENT_NOT_FOUND) { 5 Alert.alert('Not Found', 'The requested document doesn\'t exist'); 6 } else { 7 Alert.alert('Error', error.message); 8 } 9}
1const [loading, setLoading] = useState(false); 2 3const handleOperation = async () => { 4 setLoading(true); 5 try { 6 await performOperation(); 7 } finally { 8 setLoading(false); // Always reset loading 9 } 10};
The listener hooks (useFirestoreDocumentListener
, useFirestoreCollectionListener
) automatically clean up their subscriptions when the component unmounts. You can also call the returned unsubscribe
function manually if you need to stop listening earlier.
1useEffect( 2 () => { 3 const unsubscribe = useFirestoreDocumentListener({ 4 // ... params 5 }); 6 7 // The listener is active. 8 9 return () => { 10 unsubscribe(); // This is called on unmount. 11 }; 12 }, 13 [ 14 /* dependencies */ 15 ] 16);
Full TypeScript support with generics for type-safe data handling:
1interface User { 2 id: string; 3 name: string; 4 email: string; 5} 6 7// Type-safe document retrieval 8const user = await getDocument<User>({ ... }); // user is User | null 9 10// Type-safe collection retrieval 11const users = await getCollection<User>({ ... }); // users is User[] 12 13// Type-safe listeners 14useFirestoreDocumentListener<User>({ 15 onSuccess: (user) => { 16 // user is typed as User | null 17 } 18});
1const handleAddUser = useCallback(async () => { 2 // Your operation 3}, [dependencies]);
Listener hooks automatically handle cleanup. If you need to stop listening based on some application logic, you can call the unsubscribe
function that the hook returns.
1const unsubscribe = useFirestoreCollectionListener({ ... }); 2 3// Later, perhaps in a button press handler: 4const handleStopListening = () => { 5 unsubscribe(); 6};
1// Good: Limited results 2const users = await getCollection({ 3 queries: [limit(20), where('active', '==', true)], 4}); 5 6// Avoid: Fetching all documents 7const users = await getCollection({});
MIT License - see LICENSE file for details.
Contributions are welcome! Please read our contributing guidelines and submit pull requests.
Found a bug? Please open an issue with detailed reproduction steps.
No vulnerabilities found.
No security vulnerabilities found.