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 metrics system provides several utility functions to help you work with metrics data, build timelines, and access metric configurations.
firebridgeMetric
The main utility for accessing and managing metrics.
Function Signature
firebridgeMetric(noun: string, verb: string): MetricUtils
Returns
A metric utility object with methods for:
- Managing metric configuration
- Accessing entity data
- Working with timelines
Example Usage
import { firebridgeMetric } from '@firebridge/cloud/metrics'
const metric = firebridgeMetric('product', 'purchase')
// Get metric configuration
const config = await metric.get()
// Set metric configuration
await metric.set({
units: ['day', 'week', 'month'],
timezone: 'America/New_York', // Optional: defaults to 'UTC'
dateUpdated: firestore.Timestamp.now()
})
// Access entity data
const entity = metric.entity('product-123')
Entity Methods
When you access an entity through metric.entity(entityId), you get:
Summary Methods
const entity = metric.entity('product-123')
// Get entity summary
const summary = await entity.get()
console.log(`Total: ${summary.count} events, value: ${summary.value}`)
// Set entity summary
await entity.set({
count: 100,
value: 9999.00,
lastUpdated: firestore.Timestamp.now()
})
// Increment entity values
await entity.increment({
count: 1,
value: 99.99
})
// Delete all entity data
await entity.delete()
Timeline Access
// Access timeline for a specific unit
const timeline = entity.timeline('day')
// Get timeline cursor methods
const cursor = timeline.cursor
// Increment a specific time period
await cursor.increment(firestore.Timestamp.now(), {
count: 1,
value: 99.99
})
buildTimeline
Builds aggregated timeline sections from an array of events.
Function Signature
buildTimeline(
events: TrackableEvent[],
options?: {
unit?: DateTimeUnit
timezone?: string
startingCount?: number
startingValue?: number
}
): MetricTimelineSection[]
Parameters
- events: Array of events to aggregate
- unit: Time unit for aggregation (default: ‘day’)
- timezone: IANA timezone identifier (default: ‘UTC’)
- startingCount: Initial count value (default: 0)
- startingValue: Initial value sum (default: 0)
Example
import { buildTimeline } from '@firebridge/cloud/metrics'
const events = [
{ time: timestamp1, count: 5, value: 500 },
{ time: timestamp2, count: 3, value: 300 }
]
// Build daily timeline
const dailyTimeline = buildTimeline(events, { unit: 'day' })
// Build hourly timeline with starting values
const hourlyTimeline = buildTimeline(events, {
unit: 'hour',
startingCount: 100,
startingValue: 10000
})
// Build timeline with specific timezone
const nyTimeline = buildTimeline(events, {
unit: 'day',
timezone: 'America/New_York'
})
getEventsInRange
Filters events within a specific date range.
Function Signature
getEventsInRange(
events: TrackableEvent[],
fromDate: Date,
toDate: Date
): TrackableEvent[]
Example
import { getEventsInRange } from '@firebridge/cloud/metrics'
const fromDate = new Date('2024-01-01')
const toDate = new Date('2024-01-31')
const januaryEvents = getEventsInRange(allEvents, fromDate, toDate)
Advanced Patterns
Custom Metric Wrapper
Create a typed wrapper for your metrics:
class ProductMetrics {
private metric = firebridgeMetric('product', 'purchase')
async trackPurchase(productId: string, amount: number) {
const entity = this.metric.entity(productId)
await entity.increment({
count: 1,
value: amount
})
}
async getPurchaseStats(productId: string) {
const entity = this.metric.entity(productId)
const summary = await entity.get()
return {
totalPurchases: summary.count,
totalRevenue: summary.value,
averageOrderValue: summary.value / summary.count
}
}
}
Metric Migration
Migrate metrics between different structures:
async function migrateMetrics(
oldNoun: string,
oldAction: string,
newNoun: string,
newAction: string,
entityIds: string[]
) {
const oldMetric = firebridgeMetric(oldNoun, oldAction)
const newMetric = firebridgeMetric(newNoun, newAction)
for (const entityId of entityIds) {
// Get old data
const oldEntity = oldMetric.entity(entityId)
const summary = await oldEntity.get()
if (summary) {
// Set new data
const newEntity = newMetric.entity(entityId)
await newEntity.set(summary)
}
}
}
Timeline Analysis
Analyze timeline data for insights:
async function analyzeTimeline(
noun: string,
action: string,
entityId: string,
unit: DateTimeUnit
) {
const events = await fetchEventsFromDatabase(entityId)
const timeline = buildTimeline(events, { unit })
// Find peak period
const peak = timeline.reduce((max, section) =>
section.count > max.count ? section : max
)
// Calculate growth
const first = timeline[0]
const last = timeline[timeline.length - 1]
const growthRate = (last.totalValue - first.totalValue) / first.totalValue
return {
peakPeriod: peak.startTime.toDate(),
peakCount: peak.count,
totalGrowth: `${(growthRate * 100).toFixed(2)}%`
}
}
Batch Processing
Process metrics in batches for better performance:
async function batchProcessMetrics(
events: Array<{ entityId: string; event: TrackableEvent }>
) {
// Group events by entity
const eventsByEntity = events.reduce((acc, { entityId, event }) => {
if (!acc[entityId]) acc[entityId] = []
acc[entityId].push(event)
return acc
}, {} as Record<string, TrackableEvent[]>)
// Process each entity's events
const promises = Object.entries(eventsByEntity).map(([entityId, events]) =>
updateMetric('product', 'view', entityId, events)
)
await Promise.all(promises)
}
Timezone Examples
Set up metrics to aggregate based on local business hours:
// Configure metrics for a New York-based account
await firebridgeMetric('order', 'completed').set({
units: ['hour', 'day', 'month'],
timezone: 'America/New_York',
dateUpdated: firestore.Timestamp.now()
})
// Configure metrics for a London-based account
await firebridgeMetric('order', 'completed').set({
units: ['hour', 'day', 'month'],
timezone: 'Europe/London',
dateUpdated: firestore.Timestamp.now()
})
Multi-Region Support
Handle metrics for different regions with appropriate timezones:
const regions = {
'us-east': 'America/New_York',
'us-west': 'America/Los_Angeles',
'eu-west': 'Europe/London',
'asia-pacific': 'Asia/Tokyo'
}
// Configure metrics per region
for (const [region, timezone] of Object.entries(regions)) {
await firebridgeMetric(`sales-${region}`, 'transaction').set({
units: ['day', 'week', 'month'],
timezone,
dateUpdated: firestore.Timestamp.now()
})
}
Timezone-Aware Event Tracking
When events cross day boundaries, they’re correctly assigned:
// Event at 11 PM Pacific Time
const event = {
time: firestore.Timestamp.fromDate(new Date('2024-01-15T23:00:00-08:00')),
value: 100
}
// With Pacific timezone, this goes to Jan 15
await incrementMetric('sales', 'revenue', 'store-123', event)
// With UTC, this would go to Jan 16 (since 11 PM PST = 7 AM UTC next day)
- Use appropriate time units: Don’t track by second if you only need daily data
- Batch updates: Use
updateMetric for multiple events instead of individual incrementMetric calls
- Clean old data: Periodically remove old timeline data you no longer need
- Index considerations: Firestore automatically indexes the metric paths
- Timezone performance: Timezone calculations add minimal overhead and are cached by Luxon
See Also