Documentation Index
Fetch the complete documentation index at: https://firebridge.dev/llms.txt
Use this file to discover all available pages before exploring further.
The updateMetric function allows you to update metrics with multiple events at once, perfect for importing historical data, rebuilding metrics, or processing batched events.
Function Signature
updateMetric(
noun: string,
action: string,
entity: string,
events: TrackableEvent[],
options?: {
startingCount?: number
startingValue?: number
clean?: boolean
}
): Promise<void>
Parameters
Required Parameters
- noun
string: The entity type being tracked
- action
string: The action being measured
- entity
string: The specific entity ID
- events
TrackableEvent[]: Array of events to process
TrackableEvent Structure
type TrackableEvent = {
time: firestore.Timestamp
count?: number // defaults to 1
value?: number // defaults to 0
}
Optional Parameters
- startingCount
number: Initial count before events (default: 0)
- startingValue
number: Initial value before events (default: 0)
- clean
boolean: Delete existing data before update (default: true)
How It Works
- Retrieves metric configuration including time units and timezone settings
- If
clean is true, deletes all existing data for the entity
- Sorts events chronologically
- Builds timeline aggregations for each configured unit using the configured timezone
- Executes batch update for all timeline sections
- Updates entity summary with final totals
Timezone Handling: All timeline aggregations respect the configured timezone, ensuring events are grouped into the correct time periods based on local time boundaries rather than UTC.
Examples
Import Historical Data
import { updateMetric } from '@firebridge/cloud/metrics'
import { firestore } from 'firebase-admin'
// Import purchase history
const purchaseEvents = [
{
time: firestore.Timestamp.fromDate(new Date('2024-01-15')),
count: 3,
value: 299.97
},
{
time: firestore.Timestamp.fromDate(new Date('2024-01-20')),
count: 1,
value: 99.99
},
{
time: firestore.Timestamp.fromDate(new Date('2024-02-01')),
count: 2,
value: 199.98
}
]
await updateMetric('product', 'purchase', 'product-123', purchaseEvents)
Rebuild Metrics from Existing Data
// Fetch events from your database
const events = await db.collection('orders')
.where('productId', '==', 'product-123')
.get()
// Transform to TrackableEvent format
const trackableEvents = events.docs.map(doc => ({
time: doc.data().createdAt,
count: doc.data().quantity,
value: doc.data().totalPrice
}))
// Rebuild metrics
await updateMetric('product', 'purchase', 'product-123', trackableEvents, {
clean: true // Clear existing data first
})
Append to Existing Metrics
// Add new events without deleting existing data
await updateMetric('user', 'login', 'user-456', newLoginEvents, {
clean: false, // Keep existing data
startingCount: 150, // Previous total count
startingValue: 150 // Previous total value
})
Process Batch Events
// Process a batch of different event types
const viewEvents = pageViews.map(view => ({
time: view.timestamp,
count: 1
}))
await updateMetric('page', 'view', 'homepage', viewEvents)
Batch Operations
updateMetric uses Firestore batch operations for efficiency:
// Instead of 100 individual writes...
for (const event of events) {
await incrementMetric('product', 'view', 'product-123', event)
}
// Use a single batch operation
await updateMetric('product', 'view', 'product-123', events)
Timeline Building
The function efficiently builds aggregated timelines:
- Groups events by time period
- Calculates running totals
- Creates only necessary timeline sections
Advanced Usage
Custom Time Units and Timezone
Configure metrics with specific time units and timezone before updating:
import { firebridgeMetric } from '@firebridge/cloud/metrics'
// Configure hourly and daily aggregation in UTC (default)
const metric = firebridgeMetric('api', 'request')
await metric.set({
units: ['hour', 'day'],
dateUpdated: firestore.Timestamp.now()
})
// Configure with timezone for regional metrics
await metric.set({
units: ['hour', 'day'],
timezone: 'Europe/London', // GMT/BST
dateUpdated: firestore.Timestamp.now()
})
// Now update with events - timeline will use London timezone
await updateMetric('api', 'request', 'endpoint-1', apiRequests)
Migration Example
Migrate from an old analytics system with timezone awareness:
// Configure metric with appropriate timezone first
await firebridgeMetric('product', 'analytics').set({
units: ['day', 'week', 'month'],
timezone: 'America/Chicago', // Central Time for this dataset
dateUpdated: firestore.Timestamp.now()
})
// Fetch old analytics data
const oldData = await fetchLegacyAnalytics()
// Transform to events
const events = oldData.map(record => ({
time: firestore.Timestamp.fromDate(record.date),
count: record.hits,
value: record.revenue || 0
}))
// Import all at once - events will be aggregated using Central Time
await updateMetric('product', 'analytics', productId, events, {
clean: true // Start fresh
})
Cross-Timezone Event Processing
Handle events from multiple timezones correctly:
// Events from different regions with explicit timezone info
const globalEvents = [
// New York event at 9 AM Eastern
{
time: firestore.Timestamp.fromDate(new Date('2024-01-15T09:00:00-05:00')),
count: 10,
value: 1000
},
// London event at 2 PM GMT
{
time: firestore.Timestamp.fromDate(new Date('2024-01-15T14:00:00+00:00')),
count: 15,
value: 1500
}
]
// Process with company headquarters timezone
await firebridgeMetric('global', 'transaction').set({
units: ['day', 'month'],
timezone: 'America/New_York' // All events aggregated to Eastern Time
})
await updateMetric('global', 'transaction', 'worldwide', globalEvents)
Error Handling
try {
await updateMetric('product', 'purchase', 'product-123', events)
} catch (error) {
if (error.code === 'resource-exhausted') {
// Too many events, split into batches
const batchSize = 500
for (let i = 0; i < events.length; i += batchSize) {
const batch = events.slice(i, i + batchSize)
await updateMetric('product', 'purchase', 'product-123', batch, {
clean: i === 0 // Only clean on first batch
})
}
}
}
See Also