I'm trying to recover some data removed from production using Firestore's point-in-time-recovery (PITR) feature. I used the code provided in the documentation (Client Libraries -> Node), tweaked slightly as given below:
import { initializeApp } from 'firebase/app'
import { runTransaction, Timestamp, getFirestore } from 'firebase/firestore'
import { doc } from 'firebase/firestore'
/* config is specified here */
const firebaseApp = initializeApp(config)
const db = getFirestore(firebaseApp);
const readTimestamp = Timestamp.fromMillis(1741438800);
console.log("Fetching...");
const querySnapshot = await runTransaction(
db,
updateFunction => updateFunction.get(doc(db, 'collectionName', 'docName', 'collectionName', 'docName')),
{ readOnly: true, readTime: readTimestamp }
);
console.log(JSON.stringify(querySnapshot.data(), null, 2));
This code targets the right database and retrieves the correct collection - it just doesn't get data from the past.
I took a number of measures to make sure I wasn't just seeing things. First, I added a junk field ('ignoreField' : 'foo') to the record to verify that I wasn't getting data from the past - and, sure enough, all subsequent requests included that junk field in the output, regardless of which timestamps I requested.
I changed the timestamps to a day ago, 2 days ago, 5 days ago, 7 days ago, 10 days ago, and beyond - and I kept getting the same result. This is unusual both because data from the past shouldn't have included stuff I just put it, and PITR only goes back 7 days, so I shouldn't be getting anything back when requesting outside of that range. The only time I managed to get an error back was when putting an arbitrarily large number in for the timestamp (ending with 6 zeros, so it's definitely complying with the minute-granularity requirement).
I'm stumped. How can I get my PITR requests to actually retrieve data from the past?
I'm trying to recover some data removed from production using Firestore's point-in-time-recovery (PITR) feature. I used the code provided in the documentation (Client Libraries -> Node), tweaked slightly as given below:
import { initializeApp } from 'firebase/app'
import { runTransaction, Timestamp, getFirestore } from 'firebase/firestore'
import { doc } from 'firebase/firestore'
/* config is specified here */
const firebaseApp = initializeApp(config)
const db = getFirestore(firebaseApp);
const readTimestamp = Timestamp.fromMillis(1741438800);
console.log("Fetching...");
const querySnapshot = await runTransaction(
db,
updateFunction => updateFunction.get(doc(db, 'collectionName', 'docName', 'collectionName', 'docName')),
{ readOnly: true, readTime: readTimestamp }
);
console.log(JSON.stringify(querySnapshot.data(), null, 2));
This code targets the right database and retrieves the correct collection - it just doesn't get data from the past.
I took a number of measures to make sure I wasn't just seeing things. First, I added a junk field ('ignoreField' : 'foo') to the record to verify that I wasn't getting data from the past - and, sure enough, all subsequent requests included that junk field in the output, regardless of which timestamps I requested.
I changed the timestamps to a day ago, 2 days ago, 5 days ago, 7 days ago, 10 days ago, and beyond - and I kept getting the same result. This is unusual both because data from the past shouldn't have included stuff I just put it, and PITR only goes back 7 days, so I shouldn't be getting anything back when requesting outside of that range. The only time I managed to get an error back was when putting an arbitrarily large number in for the timestamp (ending with 6 zeros, so it's definitely complying with the minute-granularity requirement).
I'm stumped. How can I get my PITR requests to actually retrieve data from the past?
Share Improve this question edited Mar 15 at 18:07 Doug Stevenson 318k36 gold badges456 silver badges473 bronze badges Recognized by Google Cloud Collective asked Mar 15 at 17:04 Daniel AngresDaniel Angres 11 bronze badge1 Answer
Reset to default 0This is probably not correct:
const readTimestamp = Timestamp.fromMillis(1741438800);
Note that the examples in the documentation you linked use the Timestamp object constructor:
new Firestore.Timestamp(1684098540, 0)
The Timestamp constructor takes two numbers: seconds and nanoseconds. If your value "1741438800" is measured in seconds since unix epoch (which it probably is, if you mean for it to be "Sat Mar 08 2025 13:00:00 GMT+0000"), then you should use the Timestamp constructor instead of Timestamp.fromMillis, which (I think obviously) takes a unix epoch values in milliseconds.