Skip to content

Keep data between runs

By default, every start of Firenook begins with empty data. Add --keep-data and Firestore, Auth and Storage pick up where you left them, with no export at the stop and no import at the start. This page explains where the data lives, what is kept, and how to start fresh.

Terminal window
npx firenook emulators:start --keep-data

The first start begins empty and says where the data goes:

firenook 0.2.0
demo-shop · a fresh start
Node 24.20.0 · data in .firenook/state

Stop with q or Ctrl-C, and Firenook saves the data before it exits:

19:41:54 ✓ stopped 102 ms everything is kept in .firenook/state

Every later start picks the data up, says when it was saved, and counts what it holds:

firenook 0.2.0
demo-shop · picking up the data saved just now
Node 24.20.0 · data in .firenook/state
Firestore ✓ 32 ms 5 documents
Auth ✓ 32 ms 1 user
Storage ✓ 32 ms 1 object

The “saved” time is when the data’s files were last written: just now under a minute, then 12 minutes ago, 3 hours ago and 2 days ago.

Each start gets a new, empty working directory, .firenook/runs/session-<id>/state, and says so:

firenook 0.2.0
demo-shop · a fresh start
Node 24.20.0 · data in .firenook/runs/session-VLd3PD, for this run
19:42:21 ✓ stopped 63 ms this run's data stays in .firenook/runs/session-VLd3PD

Old runs stay on disk and are never loaded again. Firenook never deletes them, so remove old session-* folders yourself when you no longer need them.

  • Directory.firenook/
    • Directorystate/ data kept with –keep-data
      • Directoryfirestore/
        • firenook.redb the Firestore store
      • Directorystorage/ objects and their metadata
        • …
      • auth-state.json
      • native-state.json the receipt: project, buckets and seed
    • Directoryruns/
      • Directorysession-Uj2lKW/ one folder per start, with its launch receipt
        • …
    • Directoryexports/ snapshots taken with the e key
      • …

firenook init adds .firenook/ to your .gitignore. The data is a working store, not an export: copy it to another machine as an export instead.

Kept Not kept
Firestore documents Pub/Sub topics, subscriptions and messages
Auth users, tenants and the Auth configuration Cloud Tasks queues and tasks
Storage objects and their metadata Paused schedules: every start runs them all

The official emulator keeps no Pub/Sub or Cloud Tasks data either.

Because the receipt covers all three, --keep-data needs Firestore, Auth and Storage running together. Starting with --only and without one of them fails:

suite failed: --resume-state requires the firestore, auth and storage services (the native state receipt covers all three)

The start command firenook init writes uses --keep-data. If you set a project up without Auth or Storage, remove --keep-data from its emulators script, and keep data with an export instead (export and snapshots).

--keep-data works with --import. The first start imports the seed into .firenook/state, every later start picks the data up, and the seed folder is never written:

Terminal window
npx firenook emulators:start --import ./data --keep-data

Seeds and imports covers what happens when the seed changes.

--keep-data is short for --state-dir ./.firenook/state --resume-state. Name another folder with --state-dir to keep separate data, for example one per seed or per experiment:

Terminal window
npx firenook emulators:start --state-dir ./.firenook/checkout-tests --resume-state

The state folder must not hold your seed, your export folder or the project itself. Without --resume-state, Firenook refuses a folder that already holds data, rather than reset it or import into it again:

Firenook: Existing nonempty state requires explicit --resume-state (or --keep-data); never silently reimport or reset it

Only one Firenook can use a state folder at a time. A second start on the same folder stops with in use by another Firenook; see recovery.

Press q or Ctrl-C in the terminal. Firenook stops the emulators, saves the data and closes its files, then exits:

⠋ stopping 958 ms saving your data

Closing the terminal window stops it the same way. In a script, send SIGINT or SIGTERM to the firenook process and wait for it to exit.

A firenook command ended with kill -9 stops its engine too: the engine saves the data, closes it and frees the ports within a moment, and the next start picks the data up as after any stop. Killing the engine itself is different: Firestore loses nothing, but the next start checks the store and repairs it if it needs to. See recovery after a crash.

Firenook never deletes kept data. To start again from nothing, stop Firenook, then move or delete the folder:

Terminal window
rm -rf .firenook/state

Or keep the old data and start a new set beside it with another --state-dir. To keep a copy you can load anywhere, take an export first.

Data an earlier release kept opens in 0.2.0 as it is. On that first start, 0.2.0 builds its ordered field index once, with one read of every document: 7.4 s for 211,202 documents, and 49 s for 2.7 million, on the benchmark server. The plain log says when it is done:

firenook: indexed the top-level fields of 1000 Firestore documents in 0.0 s

Every start after that opens the data at once. Data saved by 0.2.0 opens in 0.2.0-next.8, which rebuilds its own index the same way. Data kept without a seed needs 0.2.0-next.7 or later: 0.2.0-next.6 refuses it and changes nothing.

Start your kept data from an export with seeds and imports.