Firepower is a utility library that provides a streamlined interface for working with Firebase services, particularly Firestore and Cloud Functions.
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.
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
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'})
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
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
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
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')
])
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
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)
}
}
)
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()
Watches a collection for real-time updates.
options
: Similar towatchDoc
optionscolPath
: 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)
})
}
)
Watches a collection group for real-time updates.
- Similar to
watchCol
but for collection groups queryAdditions
: Array of query modifier functions
Special FieldPath to refer to document ID in queries.
Creates an increment FieldValue.
Creates a server timestamp FieldValue.
Creates an array union FieldValue.
Creates an array remove FieldValue.
Creates a field delete FieldValue.
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
→Date
objects- Nested arrays and objects are recursively converted
GeoPoint
andFieldValue
objects 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 objects
Wrapper around Firestore collection snapshots:
docs
: Array ofFirepowerDocSnap
instances 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.
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)
]
}
})
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)
]
}
}
})
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.)
The DataComparison
class is a general-purpose utility for comparing any two objects:
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