# Firestore

> Seed Firestore and check the documents your services write.

Source: https://axx.nimbusxr.us/references/packs/gcp-firestore/

Seed Firestore and check the documents your services write.

The steps use the scenario's project (`the {word} gcp project with the following properties:`, from gcp-core) and its default database.

A **seed** is a YAML or JSON file that maps collections to their documents, by ID (a collection can be nested: `shipments/SHP-1/scans`):

```yaml
shipments:
  SHP-1001:
    carrier: KESTREL
    weightKg: 2.5
    agreedPrice: 3.38
    weighedAt: 2026-09-24T07:40:00Z
    manifest: "2026-09-24"
```

**Dates:** an unquoted YAML date is a Firestore timestamp (`weighedAt` above). A date alone (`2026-09-24`) is midnight UTC. A date and time can have fractional seconds and an offset (`2026-09-24T09:40:00.25+02:00`), and without an offset it is in UTC. A value tagged `!!timestamp` is a timestamp too. Quote a date to keep it a string (`manifest`). JSON has no date type, so the dates of a JSON seed are strings.

**Checks** wait (10 seconds unless `within {duration}` says otherwise): for a document at a path (`invoices/INV-2026-09-KESTREL`) to have properties, or for a collection to have a document meeting every condition. Conditions and properties are `field | value` rows, with a dotted path into maps (`totals.billed`), compared as text: timestamps in RFC 3339 and UTC (`2026-09-24T07:40:00Z`), `null` for null and `undefined` for absent. A collection check reads up to 5,000 of its documents.

Add it to a project with `axx pack add gcp-firestore`; it builds on [`gcp-core`](https://axx.nimbusxr.us/references/packs/gcp-core/), which comes with it.

## Steps

### `gcp-firestore.seed`

```gherkin
Given a {filepath} firestore seed
```

Write the documents of a seed file: YAML or JSON that maps collections to their documents, by ID. Whole numbers are stored as integers, other numbers as doubles. Unquoted YAML dates (`2026-09-24`, `2026-09-24T07:40:00Z`) and values tagged `!!timestamp` are stored as timestamps; quote a date to store it as a string.

| Parameter | Takes | For example |
|---|---|---|
| `{filepath}` | a file of the project: a path relative to the feature file's directory, the `resources` directories or axx.yaml's directory (looked for in that order), or an absolute path, quoted when it has a space | `seeds/parcels.yaml`, `kafka/scan-delivered.json` |

**Example:**

```gherkin
Given a seeds/shipments.yaml firestore seed
```

_Since 0.1.0._

### `gcp-firestore.document`

```gherkin
Then [[within {duration} ]]the {word} firestore document has the following properties:
  | field | value |
```

The table may start with the row naming its columns, as above, or go straight to its rows.

Check that the document at that path, like `invoices/INV-2026-09-KES1`, has those values in those fields.

- The check waits for it: 10 seconds, or `within {duration}`.
- Values compare as text: timestamps in RFC 3339 and UTC, references as their path, bytes in base64, a geo point as its `lat` and `lng`; `null` for null and `undefined` for absent.

| Parameter | Takes | For example |
|---|---|---|
| `{duration}` | a duration in seconds (`s`) or minutes (`m`) | `5s`, `2m` |
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |

Each row names a field of the document, or a dotted path into a map (`totals.billed`), and the value it has.

**Variants**, the parts in `[[...]]` said or left out:

- `the {word} firestore document has the following properties:`
- `within {duration} the {word} firestore document has the following properties:`

**Example:**

```gherkin
Then within 30s the invoices/INV-2026-09-KES1 firestore document has the following properties:
  | status          | RECONCILED |
  | lines           | 2          |
  | totals.billed   | 6.58       |
  | totals.disputed | 0          |
```

_Since 0.1.0._

### `gcp-firestore.collection`

```gherkin
Then [[within {duration} ]]the {word} firestore collection has a document where:
  | field | value |
```

The table may start with the row naming its columns, as above, or go straight to its rows.

Check that the collection has a document with those values in those fields.

- The check waits for it: 10 seconds, or `within {duration}`.
- Values compare as text: timestamps in RFC 3339 and UTC, references as their path, bytes in base64, a geo point as its `lat` and `lng`; `null` for null and `undefined` for absent.
- The check reads up to 5,000 documents of the collection.

| Parameter | Takes | For example |
|---|---|---|
| `{duration}` | a duration in seconds (`s`) or minutes (`m`) | `5s`, `2m` |
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |

Each row names a field of the document, or a dotted path into a map (`totals.billed`), and the value it has.

**Variants**, the parts in `[[...]]` said or left out:

- `the {word} firestore collection has a document where:`
- `within {duration} the {word} firestore collection has a document where:`

**Example:**

```gherkin
Then the shipments firestore collection has a document where:
  | parcel   | PX-5105 |
  | carrier  | HERON   |
  | weightKg | 3.2     |
```

_Since 0.1.0._
