google_cloud_firestore 0.5.4 copy "google_cloud_firestore: ^0.5.4" to clipboard
google_cloud_firestore: ^0.5.4 copied to clipboard

A Dart client library for Google Cloud Firestore, a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud.

A Dart client library for Google Cloud Firestore.

This package provides a complete API for interacting with Google Cloud Firestore, including support for documents, collections, queries, transactions, batches, and bulk writes.

It can be used standalone or as part of the Firebase Admin SDK.

Installation #

Add google_cloud_firestore to your pubspec.yaml:

dart pub add google_cloud_firestore

Usage #

Initialization #

Usage with Firebase Functions

When running inside Firebase Functions, the environment is automatically configured with Application Default Credentials. You can simply instantiate Firestore without any arguments.

import 'package:firebase_functions/firebase_functions.dart';
import 'package:google_cloud_firestore/google_cloud_firestore.dart';

void main(List<String> args) async {
  await fireUp(args, (firebase) {
    // Example: HTTPS callable function that reads from Firestore
    firebase.https.onCall(
      name: 'getUserData',
      (request, response) async {
        final data = request.data as Map<String, dynamic>?;
        final userId = data?['userId'] as String?;
        
        if (userId == null) {
          throw InvalidArgumentError('userId is required');
        }
        
        final firestore = firebase.adminApp.firestore();
        final snapshot = await firestore.collection('users').doc(userId).get();
        
        if (!snapshot.exists) {
          throw NotFoundError('User not found');
        }
        
        return CallableResult(snapshot.data());
      },
    );
  });
}

Usage with Firebase Admin SDK

If you are using the firebase_admin_sdk package, you can access Firestore via the FirebaseApp instance.

import 'package:firebase_admin_sdk/firebase_admin_sdk.dart';
import 'package:google_cloud_firestore/google_cloud_firestore.dart';

final app = FirebaseApp.initializeApp();
final firestore = app.firestore(); // Returns a Firestore instance from this package

Standalone Usage

You can initialize Firestore directly using Application Default Credentials or by providing a service account.

import 'dart:io';
import 'package:google_cloud_firestore/google_cloud_firestore.dart';

// Option 1: Use Application Default Credentials (ADC)
// Recommended for Google environments like Cloud Run, App Engine, etc.
// The project ID is discovered automatically from the environment.
final firestore = Firestore();

// Option 2: With a service account file
final firestoreWithSA = Firestore(
  settings: Settings(
    credential: Credential.fromServiceAccount(
      File('path/to/service-account.json'),
    ),
  ),
);

// Option 3: With explicit parameters
final firestoreWithParams = Firestore(
  settings: Settings(
    projectId: 'my-project',
    credential: Credential.fromServiceAccountParams(
      email: 'xxx@xxx.iam.gserviceaccount.com',
      privateKey: '-----BEGIN PRIVATE KEY-----...',
      projectId: 'my-project',
    ),
  ),
);

Using ADC locally with gcloud auth

When authenticating locally via gcloud auth application-default login, the credentials produced (type: authorized_user) do not include a project ID. You must supply it either via an environment variable or in Settings:

export GOOGLE_CLOUD_PROJECT=your-project-id
// Or set it explicitly in Settings
final firestore = Firestore(
  settings: Settings(projectId: 'your-project-id'),
);

Basic Operations #

Set / Update / Delete

final ref = firestore.collection('users').doc('user-id');

// Set a document (creates or overwrites)
await ref.set({'name': 'John Doe', 'age': 27});

// Update specific fields
await ref.update({'age': 28});

// Delete a document
await ref.delete();

Get / Query

// Get a single document
final snapshot = await firestore.collection('users').doc('user-id').get();
if (snapshot.exists) {
  print(snapshot.data());
}

// Query a collection
final querySnapshot = await firestore
    .collection('users')
    .where('age', WhereFilter.greaterThan, 18)
    .orderBy('age', descending: true)
    .get();

for (final doc in querySnapshot.docs) {
  print('${doc.id} => ${doc.data()}');
}

Firestore Pipeline Operations #

Enterprise edition only. Pipelines require a Firestore Enterprise edition database. Calling execute() against a Standard edition database fails with a FirestoreException carrying an unimplemented status.

Pipelines are server-side queries built as a chain of stages. Each stage takes the previous stage's output and produces the next, ending in execute().

final snapshot = await firestore
    .pipeline()
    .collection('books')
    .where(field('rating').greaterThan(4.0))
    .sort([field('rating').descending()])
    .select(['title', field('rating')])
    .limit(10)
    .execute();

for (final result in snapshot.results) {
  print(result.data());
}

Runnable examples for every stage live in example/pipeline_example.dart.

Sources

A pipeline starts from exactly one source, via firestore.pipeline().

Source Description
collection(path) Documents in a single collection.
collectionReference(ref) Same, from a CollectionReference.
collectionGroup(id) Every collection with the given ID.
database() Every document in the database.
documents([refs]) An explicit set of documents.
createFrom(query) An existing Query or VectorQuery.
firestore.pipeline().collection('books');
firestore.pipeline().collectionReference(firestore.collection('books'));
firestore.pipeline().collectionGroup('books');
firestore.pipeline().database();
firestore.pipeline().documents([firestore.doc('books/book-1')]);

Stages

where — keeps documents matching a boolean expression.

.where(and([
  field('genre').equal('fiction'),
  field('rating').greaterThan(4.0),
]))

select — chooses or computes the output fields. Entries may be field-name strings, field(...) references, or aliased expressions. Computed expressions must be aliased.

.select([
  'title',
  field('rating'),
  field('title').toUpperCase().as('shoutedTitle'),
])

addFields / removeFields — add computed fields to, or drop fields from, the documents flowing through.

.addFields([field('price').multiply(1.2).as('priceWithTax')])
.removeFields(['internalNotes'])

aggregate — reduces documents to aggregates, optionally grouped. Both accumulators and groups are projections.

.aggregate(
  [
    PipelineFunctions.count().as('bookCount'),
    field('rating').average().as('averageRating'),
  ],
  groups: ['genre'],
)

distinct — unique combinations of the given groups.

.distinct(['genre', field('language')])

sort, offset, limit — ordering and pagination.

.sort([field('rating').descending(), field('title').ascending()])
.offset(20)
.limit(10)

unnest — emits one document per array element. The selectable's alias names the field each element lands on; indexField records its position.

.unnest(field('tags').as('tag'), indexField: 'tagIndex')

replaceWith — promotes a map to the top level, so each of its keys becomes a document field.

.replaceWith('metadata')

union — concatenates another pipeline's results, keeping duplicates.

.union(firestore.pipeline().collection('archivedBooks'))

sample — pseudo-randomly keeps a fixed number of documents, or a proportion between 0 and 1. Exactly one of the two must be given.

.sample(documents: 10)
.sample(percentage: 0.25)

findNearest — vector nearest-neighbour search. Needs a vector index; see E2E Testing for the gcloud invocation.

.findNearest(
  vectorField: 'embedding',
  queryVector: FieldValue.vector([1, 2, 3]),
  distanceMeasure: DistanceMeasure.cosine,
  limit: 3,
  distanceResultField: 'distance',
)

rawStage — escape hatch for preview stages this SDK does not yet wrap. search is a thin wrapper over the same mechanism.

.rawStage('sample', [10, 'documents'], options: {'stable': true})

Query-level options are passed to execute() rather than built onto the Pipeline, so a Pipeline value stays a pure description of what to fetch. Use rawOptions for options this SDK does not wrap yet; they take precedence.

.execute(
  indexMode: PipelineIndexMode.recommended,
  explain: const PipelineExplainOptions(
    mode: PipelineExplainMode.analyze,
    outputFormat: PipelineExplainOutputFormat.text,
  ),
)

Expressions

Expressions come from two interchangeable entry points:

  • Top-level helpers and fluent methodsfield, constant, variable, and, or, not, the comparison helpers, then chained methods.
  • PipelineFunctions — the full catalog as static methods, useful when you want the function form or a helper without a fluent equivalent.
// Equivalent:
field('title').toUpperCase();
PipelineFunctions.toUpper('title');

Expression.field / Expression.constant are aliases for the top-level field / constant, for callers who prefer a namespaced entry point.

Field arguments vs value arguments. A String in a field position means a field reference; in a value position it stays a string literal. The field position is the first argument of most helpers:

// Reads the `title` field, compares against the literal "Harry":
PipelineFunctions.startsWith('title', 'Harry');

// Compare two fields by wrapping the value position explicitly:
PipelineFunctions.startsWith('title', field('prefix'));

Selected expressions must be aliased with as (or alias):

.select([field('createdAt').timestampToUnixSeconds().as('createdSeconds')])
Function reference

Dart helpers map onto backend function names as follows. Every name below is available on PipelineFunctions; most also exist as a fluent method.

Category Dart Backend
Comparison equal, notEqual, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual, cmp equal, not_equal, less_than, less_than_or_equal, greater_than, greater_than_or_equal, cmp
Logical and, or, xor, nor, not, conditional, ifNull, coalesce, switchOn, equalAny, notEqualAny and, or, xor, nor, not, conditional, if_null, coalesce, switch_on, equal_any, not_equal_any
Aggregate count, countAll, countIf, countDistinct, sum, average, minimum, maximum, first, last, arrayAgg, arrayAggDistinct count, count_if, count_distinct, sum, average, minimum, maximum, first, last, array_agg, array_agg_distinct
Arithmetic add, subtract, multiply, divide, mod, abs, ceil, floor, round, trunc, sqrt, pow, exp, ln, log, log10, rand, logicalMinimum, logicalMaximum add, subtract, multiply, divide, mod, abs, ceil, floor, round, trunc, sqrt, pow, exp, ln, log, log10, rand, minimum, maximum
Array array, arrayConcat, arrayContains, arrayContainsAll, arrayContainsAny, arrayFilter, arrayGet, arrayLength, arrayReverse, arrayFirst, arrayFirstN, arrayLast, arrayLastN, arrayIndexOf, arrayIndexOfAll, arrayLastIndexOf, arraySlice, arrayTransform, arrayMaximum, arrayMaximumN, arrayMinimum, arrayMinimumN, arraySum, maximumN, minimumN, join array, array_concat, array_contains, array_contains_all, array_contains_any, array_filter, array_get, array_length, array_reverse, array_first, array_first_n, array_last, array_last_n, array_index_of, array_index_of_all, array_index_of, array_slice, array_transform, array_maximum, array_maximum_n, array_minimum, array_minimum_n, array_sum, maximum_n, minimum_n, join
String byteLength, charLength, startsWith, endsWith, like, regexContains, regexMatch, regexFind, regexFindAll, stringConcat, stringContains, stringIndexOf, toUpper, toLower, substring, stringReverse, stringRepeat, stringReplaceAll, stringReplaceOne, trim, ltrim, rtrim, split byte_length, char_length, starts_with, ends_with, like, regex_contains, regex_match, regex_find, regex_find_all, string_concat, string_contains, string_index_of, to_upper, to_lower, substring, string_reverse, string_repeat, string_replace_all, string_replace_one, trim, ltrim, rtrim, split
Generic length, reverse, concat length, reverse, concat
Map map, mapGet, getField, mapSet, mapRemove, mapMerge, mapKeys, mapValues, mapEntries map, map_get, get_field, map_set, map_remove, map_merge, map_keys, map_values, map_entries
Timestamp currentTimestamp, timestampTruncate, timestampAdd, timestampSubtract, timestampDiff, timestampExtract, timestampToUnixMicros/Millis/Seconds, unixMicrosToTimestamp/Millis/Seconds current_timestamp, timestamp_trunc, timestamp_add, timestamp_subtract, timestamp_diff, timestamp_extract, timestamp_to_unix_*, unix_*_to_timestamp
Vector cosineDistance, dotProduct, euclideanDistance, vectorLength, geoDistance cosine_distance, dot_product, euclidean_distance, vector_length, geo_distance
Reference collectionId, documentId, parent, referenceSlice, currentDocument collection_id, document_id, parent,