@acobb/firepower
v1.13.1
Published
powerful utils for firebase
Readme
Firepower
Firepower is a utility library that provides a streamlined interface for working with Firebase services, particularly Firestore and Cloud Functions.
Initialization
IMPORTANT: Before using any Firepower utilities, you must initialize the library with your Firebase instance:
import { initFirepower } from '@acobb/firepower'
import admin from 'firebase-admin'
import functions from 'firebase-functions/v1'
// Initialize with Firebase Admin SDK and Functions
initFirepower(admin, functions)
// Or just Firebase Admin SDK if not using Cloud Functions
initFirepower(admin)
// Or with Firebase Web SDK
initFirepower(firebase)The initFirepower function accepts:
firebaseBase: Required. The Firebase instance from either Firebase Admin SDK (admin) or Firebase Web SDK (firebase).functionsBase: Optional. The Firebase Functions instance (functions). Only required if you're using the Cloud Functions utilities.
Firestore Utilities
Document Operations
setDoc(options, pathOrRefOrDocOrChange, additions)
Sets a document's data in Firestore.
options: Configuration options (optional)merge: Whether to merge with existing data (default: true)transaction: Optional transaction object
pathOrRefOrDocOrChange: Path or reference to the documentadditions: Data to set in the document- Returns: Reference to the set document
updateDoc(options, pathOrRefOrDocOrChange, additions)
Updates a document's data in Firestore.
- Important: Document must exist, use dot notation for nested fields
options: Configuration options (optional)transaction: Optional transaction object
pathOrRefOrDocOrChange: Path or reference to the documentadditions: Data to update (using dot notation for nested fields)- Returns: Reference to the updated document
Example:
updateDoc(postDoc, {'postUser.lastName': 'Bittner'})addDoc(options, colPath, additions)
Adds a new document to a collection with an auto-generated ID.
options: Configuration options (optional)transaction: Optional transaction object
colPath: Path to the collectionadditions: Data for the new document- Returns: Reference to the new document
deleteDoc(options, pathOrRefOrDocOrChange)
Deletes a document from Firestore.
- Note: No error if document doesn't exist
options: Configuration options (optional)transaction: Optional transaction object
pathOrRefOrDocOrChange: Path or reference to the document- Returns: Reference to the deleted document
getDoc(options, pathOrRefOrDocOrChange)
Gets a single document from Firestore.
options: Configuration options (optional)transaction: Optional transaction object
pathOrRefOrDocOrChange: Path or reference to the document- Returns: FirepowerDocSnap wrapper around the document
Collection Operations
getCol(options, colPath, queryAdditions)
Gets a collection of documents.
options: Configuration options (optional)transaction: Optional transaction object
colPath: Path to the collectionqueryAdditions: Array of query modifier functions (optional)- Each function takes a query and returns a modified query
- Functions are applied in order
- Null or undefined functions are skipped
- Returns: FirepowerColSnap wrapper around the collection
Example:
// Single query addition
getCol('users', [
q => q.where('age', '>', 18)
])
// Multiple query additions
getCol('users', [
q => q.where('age', '>', 18),
q => q.orderBy('name'),
q => q.limit(10)
])
// With some conditional filters
const isAdmin = true
getCol('users', [
q => q.where('age', '>', 18),
isAdmin ? q => q.where('role', '==', 'admin') : null,
q => q.orderBy('name')
])getColGroup(options, colGroupName, queryAdditions)
Gets documents from a collection group (nested collections with same name).
options: Configuration optionscolGroupName: Name of the collection groupqueryAdditions: Array of query modifier functions (optional)- Returns: FirepowerColSnap wrapper
getColInBatches(options, colPath, orderByAddition, queryAdditions, limitPerBatch, batchCallback)
Gets documents from a collection in batches.
options: Configuration optionscolPath: Path to the collectionorderByAddition: Function to add ordering (default: orderBy(docIdKey(), 'asc'))queryAdditions: Array of query modifier functionslimitPerBatch: Number of documents per batchbatchCallback: Function called after each batch
Example:
// Process users in batches with multiple filters
await getColInBatches(
'users',
q => q.orderBy('createdAt', 'desc'),
[
q => q.where('status', '==', 'active'),
q => q.where('age', '>', 18)
],
100,
async batch => {
for (const doc of batch.docs) {
await processUser(doc.data)
}
}
)Real-time Updates
watchDoc(options, pathOrRefOrDocOrChange, callback)
Watches a document for real-time updates.
options: Configuration optionsupdateInterval: Optional polling interval (for admin SDK)includeMetadataChanges: Include metadata changes (default: false)onError: Error handler
pathOrRefOrDocOrChange: Path or reference to documentcallback: Function called on document updates with aFirepowerDocSnap
Example:
// Watch for changes to a user's profile
const unsubscribe = firestore.watchDoc(
'users/123',
(docSnap: FirepowerDocSnap) => {
if (docSnap.exists) {
// Access document data (automatically decoded)
console.log('Profile updated:', docSnap.data)
// Access document metadata
console.log('Document ID:', docSnap.id)
console.log('Document path:', docSnap.path)
} else {
console.log('Profile deleted')
}
}
)
// Later, when you want to stop watching:
unsubscribe()watchCol(options, colPath, queryAdditions, callback)
Watches a collection for real-time updates.
options: Similar towatchDocoptionscolPath: Path to the collectionqueryAdditions: Array of query modifier functionscallback: Function called on collection updates with aFirepowerColSnap
Example:
// Watch for new orders with multiple filters
const unsubscribe = firestore.watchCol(
'orders',
[
q => q.where('status', '==', 'pending'),
q => q.where('total', '>', 100),
q => q.orderBy('createdAt', 'desc'),
q => q.limit(20)
],
(snapshot: FirepowerColSnap) => {
console.log('Pending high-value orders:', snapshot.docs.length)
snapshot.docs.forEach(doc => {
console.log('Order:', doc.data)
})
}
)watchColGroup(options, colGroupName, queryAdditions, callback)
Watches a collection group for real-time updates.
- Similar to
watchColbut for collection groups queryAdditions: Array of query modifier functions
Field Values
docIdKey()
Special FieldPath to refer to document ID in queries.
serverIncrement(n)
Creates an increment FieldValue.
serverTimestamp()
Creates a server timestamp FieldValue.
serverArrayUnion(...elements)
Creates an array union FieldValue.
serverArrayRemove(...elements)
Creates an array remove FieldValue.
cloudDelete()
Creates a field delete FieldValue.
Snapshot Wrappers
FirepowerDocSnap
Wrapper around Firestore document snapshots with automatic data conversion. All document data is automatically decoded from Firestore format to native JavaScript types:
exists: Whether the document existsid: The document IDmetadata: The document metadataref: The document referencepath: The full document pathdata: The document data with automatic conversions:Timestamp→Dateobjects- Nested arrays and objects are recursively converted
GeoPointandFieldValueobjects are preserved as-is
Example:
const docSnap = await getDoc('users/123')
// Timestamps are automatically converted to Date objects
const createdAt = docSnap.data.createdAt // Date object
const lastLogin = docSnap.data.lastLogin // Date object
// Nested objects and arrays are also converted
const preferences = docSnap.data.preferences // All nested Timestamps are Date objects
const loginHistory = docSnap.data.loginHistory // Array of objects with Date objectsFirepowerColSnap
Wrapper around Firestore collection snapshots:
docs: Array ofFirepowerDocSnapinstances for each document in the collection- Each document's data is automatically converted as described above
colSnap: The underlying Firestore collection snapshot
Example:
const colSnap = await getCol('users')
// All documents have their Timestamps converted to Dates
colSnap.docs.forEach(doc => {
const createdAt = doc.data.createdAt // Date object
console.log(`User ${doc.id} created at:`, createdAt.toLocaleString())
})Note: When writing data back to Firestore (using setDoc, updateDoc, etc.), the library automatically converts your JavaScript Date objects back to Firestore Timestamp objects. You don't need to handle these conversions manually.
Cloud Functions
Function Triggers
onDocCreated(options, wildcardDocPath, callback)
Triggers when a new document is created in Firestore.
Parameters:
options: Configuration options (optional)timeoutSeconds: Function timeout (default: 60)memory: Memory allocation (default: '256MB')
wildcardDocPath: Path pattern to match documentscallback: Function to execute when triggered
Callback Parameters:
context: Function execution contextparams: URL parameters from the wildcard pathdocChange: DataComparison instance with document changesid: Document IDref: Document referencepath: Document path
Return Value: The callback can optionally return an object with:
updates: Object with fields to update on the triggered documentpromiseFunctions: Array of functions that return promises to be executed
Example:
onDocCreated('users/{userId}', async ({ docChange, params }) => {
const userData = docChange.newValue.data
// Return updates and async operations
return {
// Update the document with additional fields
updates: {
lastProcessed: new Date(),
status: 'processed'
},
// Run additional async operations
promiseFunctions: [
() => sendWelcomeEmail(userData.email),
() => updateUserStats(params.userId)
]
}
})onDocUpdated(options, wildcardDocPath, callback)
Triggers when a document is updated in Firestore.
Parameters:
- Same as
onDocCreated
Return Value:
- Same as
onDocCreated
Example:
onDocUpdated('orders/{orderId}', async ({ docChange }) => {
const oldStatus = docChange.oldValue?.data?.status
const newStatus = docChange.newValue.data.status
if (oldStatus !== newStatus && newStatus === 'completed') {
return {
updates: {
completedAt: new Date()
},
promiseFunctions: [
() => sendOrderConfirmation(docChange.newValue.data)
]
}
}
})onFunctionCall(options, callback)
Creates an HTTPS callable function.
Parameters:
options: Configuration options (optional)timeoutSeconds: Function timeout (default: 60)memory: Memory allocation (default: '256MB')
callback: Function to execute when called
Callback Parameters:
data: Data passed to the functioncontext: Function execution context including:auth: Authentication informationsignedInUserId: Current user's ID- Request metadata (headers, method, params, etc.)
Data Comparison
The DataComparison class is a general-purpose utility for comparing any two objects:
Methods
isEqual: Checks if two objects are equalisUnequal: Checks if two objects are not equalobjectNumericalDiff: Compares numerical differences between objectsremovedArrayValues: Identifies values removed from arraystransform(transformFn): Applies a transformation function to both objects being compared before comparison
Example usage with transform:
const comparison = new DataComparison(oldData, newData)
.transform(data => processData(data))
// The comparison will now be performed on the transformed data