TypeScript type definitions for Firebase Firestore providing comprehensive type safety for database operations
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Specialized data types for Firestore including timestamps, geographic points, binary data, and field values with their type-safe operations.
Represents a point in time with nanosecond precision.
class Timestamp {
/** Create timestamp from seconds and nanoseconds */
constructor(seconds: number, nanoseconds: number);
/** Create timestamp for current time */
static now(): Timestamp;
/** Create timestamp from JavaScript Date */
static fromDate(date: Date): Timestamp;
/** Create timestamp from milliseconds since epoch */
static fromMillis(milliseconds: number): Timestamp;
/** Seconds since Unix epoch */
readonly seconds: number;
/** Nanoseconds within the second (0-999,999,999) */
readonly nanoseconds: number;
/** Convert to JavaScript Date */
toDate(): Date;
/** Convert to milliseconds since epoch */
toMillis(): number;
/** Check if this timestamp equals another */
isEqual(other: Timestamp): boolean;
/** String representation for JSON serialization */
valueOf(): string;
}Represents a geographic location with latitude and longitude.
class GeoPoint {
/** Create geographic point */
constructor(latitude: number, longitude: number);
/** Latitude in degrees (-90 to 90) */
readonly latitude: number;
/** Longitude in degrees (-180 to 180) */
readonly longitude: number;
/** Check if this point equals another */
isEqual(other: GeoPoint): boolean;
}Represents binary data stored in Firestore.
class Blob {
private constructor();
/** Create blob from base64 string */
static fromBase64String(base64: string): Blob;
/** Create blob from byte array */
static fromUint8Array(array: Uint8Array): Blob;
/** Convert to base64 string */
toBase64(): string;
/** Convert to byte array */
toUint8Array(): Uint8Array;
/** Check if this blob equals another */
isEqual(other: Blob): boolean;
}Sentinel values for special field operations.
class FieldValue {
private constructor();
/** Server timestamp placeholder */
static serverTimestamp(): FieldValue;
/** Delete field placeholder */
static delete(): FieldValue;
/** Add elements to array field */
static arrayUnion(...elements: any[]): FieldValue;
/** Remove elements from array field */
static arrayRemove(...elements: any[]): FieldValue;
/** Increment numeric field */
static increment(n: number): FieldValue;
/** Check if this field value equals another */
isEqual(other: FieldValue): boolean;
}import type { Timestamp } from "@firebase/firestore-types";
interface Event {
name: string;
createdAt: Timestamp;
scheduledFor: Timestamp;
}
function handleTimestamps() {
// Create timestamps
const now = Timestamp.now();
const fromDate = Timestamp.fromDate(new Date('2024-01-01'));
const fromMillis = Timestamp.fromMillis(Date.now());
const precise = new Timestamp(1640995200, 500000000); // 500ms precision
// Convert timestamps
console.log('As Date:', now.toDate());
console.log('As milliseconds:', now.toMillis());
console.log('Seconds:', now.seconds);
console.log('Nanoseconds:', now.nanoseconds);
// Compare timestamps
const earlier = Timestamp.fromDate(new Date('2023-01-01'));
const later = Timestamp.fromDate(new Date('2024-01-01'));
console.log('Are equal:', earlier.isEqual(later)); // false
return { now, fromDate, fromMillis, precise };
}
async function saveEvent(docRef: DocumentReference<Event>) {
const event: Event = {
name: "Team Meeting",
createdAt: Timestamp.now(),
scheduledFor: Timestamp.fromDate(new Date('2024-12-25'))
};
await docRef.set(event);
}import type { GeoPoint } from "@firebase/firestore-types";
interface Location {
name: string;
coordinates: GeoPoint;
accuracy: number;
}
function handleGeoPoints() {
// Create geographic points
const nyc = new GeoPoint(40.7128, -74.0060);
const sf = new GeoPoint(37.7749, -122.4194);
const london = new GeoPoint(51.5074, -0.1278);
// Access coordinates
console.log(`NYC: ${nyc.latitude}, ${nyc.longitude}`);
console.log(`SF: ${sf.latitude}, ${sf.longitude}`);
// Compare points
const nycCopy = new GeoPoint(40.7128, -74.0060);
console.log('NYC equals copy:', nyc.isEqual(nycCopy)); // true
console.log('NYC equals SF:', nyc.isEqual(sf)); // false
return { nyc, sf, london };
}
async function saveLocation(docRef: DocumentReference<Location>) {
const location: Location = {
name: "Central Park",
coordinates: new GeoPoint(40.7829, -73.9654),
accuracy: 10 // meters
};
await docRef.set(location);
}
// Query by geographic proximity (requires composite index)
function queryNearby(collection: CollectionReference<Location>) {
const center = new GeoPoint(40.7829, -73.9654);
const radiusInLat = 0.01; // Approximate degrees for desired radius
return collection
.where('coordinates', '>', new GeoPoint(center.latitude - radiusInLat, -180))
.where('coordinates', '<', new GeoPoint(center.latitude + radiusInLat, 180));
}import type { Blob } from "@firebase/firestore-types";
interface FileRecord {
name: string;
content: Blob;
mimeType: string;
size: number;
}
function handleBlobs() {
// Create from base64
const base64Data = "SGVsbG8gV29ybGQ="; // "Hello World"
const blobFromBase64 = Blob.fromBase64String(base64Data);
// Create from byte array
const bytes = new Uint8Array([72, 101, 108, 108, 111]); // "Hello"
const blobFromBytes = Blob.fromUint8Array(bytes);
// Convert blob data
console.log('As base64:', blobFromBytes.toBase64());
console.log('As bytes:', blobFromBytes.toUint8Array());
// Compare blobs
const sameBytesBlob = Blob.fromUint8Array(new Uint8Array([72, 101, 108, 108, 111]));
console.log('Blobs equal:', blobFromBytes.isEqual(sameBytesBlob)); // true
return { blobFromBase64, blobFromBytes };
}
async function uploadFile(docRef: DocumentReference<FileRecord>, fileData: ArrayBuffer) {
const bytes = new Uint8Array(fileData);
const blob = Blob.fromUint8Array(bytes);
const record: FileRecord = {
name: "document.pdf",
content: blob,
mimeType: "application/pdf",
size: bytes.length
};
await docRef.set(record);
}import type { FieldValue } from "@firebase/firestore-types";
interface UserProfile {
name: string;
lastLogin: FieldValue | Timestamp;
loginCount: number;
tags: string[];
preferences?: { [key: string]: any };
}
async function useFieldValues(docRef: DocumentReference<UserProfile>) {
// Set server timestamp
await docRef.update({
lastLogin: FieldValue.serverTimestamp()
});
// Increment counter
await docRef.update({
loginCount: FieldValue.increment(1)
});
// Array operations
await docRef.update({
tags: FieldValue.arrayUnion("premium", "verified")
});
await docRef.update({
tags: FieldValue.arrayRemove("trial")
});
// Delete field
await docRef.update({
preferences: FieldValue.delete()
});
}
// Atomic batch operations with field values
async function batchFieldOperations(batch: WriteBatch, docRef: DocumentReference<UserProfile>) {
batch.update(docRef, {
lastLogin: FieldValue.serverTimestamp(),
loginCount: FieldValue.increment(1),
tags: FieldValue.arrayUnion("active")
});
await batch.commit();
}interface ComplexDocument {
id: string;
createdAt: Timestamp;
location: GeoPoint;
fileData: Blob;
metadata: {
version: number;
tags: string[];
lastModified: Timestamp;
};
}
async function handleComplexDocument(docRef: DocumentReference<ComplexDocument>) {
const complexData: ComplexDocument = {
id: "doc-123",
createdAt: Timestamp.now(),
location: new GeoPoint(37.7749, -122.4194),
fileData: Blob.fromBase64String("VGVzdCBkYXRh"), // "Test data"
metadata: {
version: 1,
tags: ["important", "draft"],
lastModified: Timestamp.now()
}
};
// Save document
await docRef.set(complexData);
// Update with field values
await docRef.update({
"metadata.version": FieldValue.increment(1),
"metadata.tags": FieldValue.arrayUnion("reviewed"),
"metadata.lastModified": FieldValue.serverTimestamp()
});
// Read and process
const snapshot = await docRef.get();
if (snapshot.exists) {
const data = snapshot.data();
console.log('Created:', data?.createdAt.toDate());
console.log('Location:', `${data?.location.latitude}, ${data?.location.longitude}`);
console.log('File size:', data?.fileData.toUint8Array().length, 'bytes');
console.log('Version:', data?.metadata.version);
}
}