Immanuel John
Immanuel John

Reputation: 291

How can I see Cloud Firestore logs?

I want to see Cloud Firestores logs like I can see for Cloud Functions for Firebase. There is a logs tab in Functions tab of the Firebase console. Similarly I want to see this for Cloud Firestore. How?

Upvotes: 16

Views: 12194

Answers (3)

Lewy
Lewy

Reputation: 71

Building on #ForrestLymans code:

exports.dbLog = functions.firestore
  .document('LICENCE/{licenceId}/{collection}/{docId}')
  .onWrite(async (change, context) => {
    try {
      const { collection, docId, licenceId } = context.params;
      const event = context.eventType;
      const created_at = admin.firestore.FieldValue.serverTimestamp();

      const licenceRef = admin.firestore().collection('LICENCE').doc(licenceId);

      // Get the current year and month
      const now = admin.firestore.Timestamp.now();
      const year = now.toDate().getFullYear();
      const month = now.toDate().getMonth() + 1; // Months are zero-based, so we add 1

      // Create the subcollection references for write and delete logs based on the year and month
      const logWriteCollectionRef = licenceRef.collection(`LOGS/writes/${year}_${month}`);
      const logDeleteCollectionRef = licenceRef.collection(`LOGS/deletes/${year}_${month}`);

      if (collection !== 'firestore_write_log' && collection !== 'firestore_delete_log') {
        if (event === 'write' && change.after.exists) {
          const data = change.after.data();

          const logRef = logWriteCollectionRef.doc();
          await logRef.set({ collection, docId, event, data, created_at });
        } else if (event === 'delete') {
          const snapshot = await admin.firestore()
            .collection(collection)
            .doc(docId)
            .get();
          if (snapshot.exists) {
            const data = snapshot.data();

            const logRef = logDeleteCollectionRef.doc();
            await logRef.set({ collection, docId, event, data, created_at });
          }
        }
      }
    } catch (error) {
      console.error('Error logging Firestore activity:', error);
    }
  });

This splits the logs per user/ top level

Upvotes: 0

ForrestLyman
ForrestLyman

Reputation: 1652

I wrote a firebase cloud function to log all activity to Firestore:

/**
 * Logs all database activity
 *
 * @type {CloudFunction<Change<DocumentSnapshot>>}
 */
exports.dbLogger = functions.firestore
  .document('{collection}/{id}')
  .onWrite(async (change, context) => {
    const {collection, id} = context.params;
    if (collection !== 'firestore_log') {
      const event = context.eventType;
      const data = change.after.data();
      const created_at = Date.now();
      admin.firestore().collection('firestore_log').add({collection, id, event, data, created_at});
    }
  });

Here's an example of the logged data:

firestore_log entry

Note that this is a quick dev only version that logs everything; in production we have Firestore rules to deny any read / write to the table (the admin on firebase functions can still access them):

// firestore.rules
match /firestore_log/{entryId} {
    allow read: if false;
    allow write: if false;
}

and filter the logged collections to avoid persisting sensitive data.

Note that if you prefer to persist this in the logs instead of Firestore you can use console.log({....}). I prefer Firestore because its designed to handle larger data sets.

Upvotes: 9

Dan McGrath
Dan McGrath

Reputation: 42018

There are currently no log entries for Cloud Firestore exposed to developers, so for the time being we recommend logging any statistics you are about separately.

Upvotes: 2

Related Questions