or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

collections-queries.mdcore-database.mddata-snapshots.mddata-types.mddocument-references.mdindex.mdtransactions-batches.md
tile.json

data-types.mddocs/

Firestore Data Types

Specialized data types for Firestore including timestamps, geographic points, binary data, and field values with their type-safe operations.

Capabilities

Timestamp Class

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;
}

GeoPoint Class

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;
}

Blob Class

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;
}

FieldValue Class

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;
}

Usage Examples

Working with Timestamps

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);
}

Geographic Points

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));
}

Binary Data

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);
}

Field Values for Special Operations

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();
}

Complex Data Type Combinations

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);
  }
}