title: Firebase onCreate trigger failing since update to Node.js 10
body: <p>We have a Firebase project with Cloud Firestore document collections. One of those collections has an .onCreate() trigger function that increments an index counter property and ultimately goes on to send a push notification to mobile app users. The function has been running perfectly for many months. Yesterday, seemingly spontaneously, the function started erroring with the following message in the Firebase function logs:</p>
  <pre><code>onCreateNotificationFeed
  Error: process.env.GCLOUD_PROJECT is not set.
      at DocumentBuilder (/workspace/node_modules/firebase-functions/lib/providers/firestore.js:99:23)
      at cloudFunctionNewSignature (/workspace/node_modules/firebase-functions/lib/cloud-functions.js:102:13)
      at cloudFunction (/workspace/node_modules/firebase-functions/lib/cloud-functions.js:151:20)
      at Promise.resolve.then (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:199:28)
      at process._tickCallback (internal/process/next_tick.js:68:7)
  </code></pre>
  <p>My research led me to conclude that this was an issue to do with Node.js 10, which struck me as very odd as my functions were all in Node.js 8. I had been aware for some time that Node.js 8 was being deprecated by Firebase but I understood that I had about a few weeks to deal with that. The deprecation notice reads:</p>
  <pre><code>From 15 Feb 2021, we'll no longer support new deploys or updates of Node.js 8 functions.
  Starting 15 Mar 2021, we'll no longer support executions of existing Node.js 8 functions.
  </code></pre>
  <p>So addressing two birds with one stone I upgraded to Node.js 10 and in doing so I have swapped one problem for another, now getting the following log errors, which I'm seeking help with now:</p>
  <pre><code>onCreateNotificationFeed
  Error: Value for argument &quot;data&quot; is not a valid Firestore document. Couldn't serialize object of type &quot;NumericIncrementTransform&quot; (found in field &quot;Count&quot;). Firestore doesn't support JavaScript objects with custom prototypes (i.e. objects that were created via the &quot;new&quot; operator).
      at validateUserInput (/workspace/node_modules/firebase-admin/node_modules/@google-cloud/firestore/build/src/serializer.js:326:15)
      at Object.validateUserInput (/workspace/node_modules/firebase-admin/node_modules/@google-cloud/firestore/build/src/serializer.js:263:13)
      at validateDocumentData (/workspace/node_modules/firebase-admin/node_modules/@google-cloud/firestore/build/src/write-batch.js:577:18)
      at WriteBatch.set (/workspace/node_modules/firebase-admin/node_modules/@google-cloud/firestore/build/src/write-batch.js:243:9)
      at /workspace/lib/functions_shared/onCreate.js:140:15
      at Generator.next (&amp;lt;anonymous&amp;gt;)
      at fulfilled (/workspace/lib/functions_shared/onCreate.js:5:58)
      at process._tickCallback (internal/process/next_tick.js:68:7) 
  </code></pre>
  <p>The Typescript code for the onCreate() function is below. It was built with tsc 4.15 and deployed to Firebase with firebase 9.3 (package.json further below). The error above seems to be referring to the declaration of 'count' at the top of the function, in this snippet, with the field &quot;Count&quot; referenced in the error:</p>
  <pre><code>const count = yield indexRef.get().then(doc =&gt; {
              var index = 0;
              if (doc.exists) {
                  index = doc.data()[&quot;Count&quot;];
              }
              return index + 1;
          })
  </code></pre>
  <p>The full function is as follows:</p>
  <pre><code>import * as functions from 'firebase-functions';
  import { db, cometChatConfig, CometChatService, FirebaseFunctionsService } from '../shared';
  import { NotificationFeed } from '../models/notificationFeeds';
  import { FieldValue } from '@google-cloud/firestore';
  
  const admin = require('firebase-admin');
  const schoolConnectionRef = db.collection('school-connections');
  const userSettingRef = db.collection('user-settings');
  const notificationFeedRef = db.collection('notification-feeds');
  
  exports.onCreateNotificationFeed = functions.firestore.document('notification-feeds/{documentId}')
      .onCreate((snap, context) =&gt; __awaiter(this, void 0, void 0, function* () {
      try {
          // Update Index number
          const increment = firestore_1.FieldValue.increment(1);
          const indexRef = notificationFeedRef.doc('--index--');
          const count = yield indexRef.get().then(doc =&gt; {
              var index = 0;
              if (doc.exists) {
                  index = doc.data()[&quot;Count&quot;];
              }
              return index + 1;
          })
              .catch(error =&gt; {
              console.log(&quot;an error occurred&quot;);
              return 1;
          });
          console.log(&quot;New notification is created ID :&quot; + snap.ref.id);
          const batch = shared_1.db.batch();
          batch.set(indexRef, { Count: increment }, { merge: true });
          batch.update(notificationFeedRef.doc(snap.ref.id), {
              index: count,
              date: admin.firestore.Timestamp.fromDate(new Date()),
              timestamp: Date.now()
          });
          batch.commit()
              .then(ref =&gt; {
              console.log('update index succeed:', ref);
          })
              .catch(error =&gt; {
              console.log('update index succeed:', error);
          });
          const newNotification = snap.data();
          // Send notification 
          let message = {
              notification: {
                  title: newNotification.title,
                  body: newNotification.shortText
              },
              apns: {
                  payload: {
                      aps: {
                          sound: &quot;default&quot;,
                          badge: 1
                      },
                  },
              },
              topic: &quot;UID_&quot; + newNotification[&quot;firebaseUserUID&quot;] //newNotification.channel
          };
          if (newNotification.withPopup) {
              return admin.messaging().send(message)
                  .then(ref =&gt; {
                  console.log('Notification sent successfully:', ref);
              })
                  .catch(error =&gt; {
                  console.log('Notification sent failed:', error);
              });
          }
      }
      catch (e) {
          console.error(&quot;SendNotification Exception&quot;);
          console.error(e);
      }
  }));
  </code></pre>
  <p>...and the referenced NotificationFeed model:</p>
  <pre><code>export class NotificationFeed {
      index: number; //Unique numbers in order
  
      firebaseUserUID: string;
      title: string;
      shortText: string;
      publishDateTime: Date;
      notificationID: number;
      pictureURL: string;
      //timestamp: number;
      linkURL: string;
      withPopup: boolean; // if true, show message only &quot;new message has arrived&quot;
  
      schoolID: string;
      syncCompleted: boolean;
   }
  </code></pre>
  <p>According to <a href="https://github.com/googleapis/nodejs-firestore/issues/143" rel="nofollow noreferrer">https://github.com/googleapis/nodejs-firestore/issues/143</a> it seems that the nodejs-firestore team explicitly decided to not support serialization of custom classes for the Web and Node.JS client, so I'm not sure how to refactor the code snippet to return 'count'.</p>
  <p>For completeness, my package.json is below</p>
  <pre><code>{
    &quot;name&quot;: &quot;functions&quot;,
    &quot;scripts&quot;: {
      &quot;lint&quot;: &quot;tslint --project tsconfig.json&quot;,
      &quot;build&quot;: &quot;tsc&quot;,
      &quot;serve&quot;: &quot;npm run build &amp;&amp; firebase serve --only functions&quot;,
      &quot;shell&quot;: &quot;npm run build &amp;&amp; firebase functions:shell&quot;,
      &quot;start&quot;: &quot;npm run shell&quot;,
      &quot;deploy&quot;: &quot;firebase deploy --only functions&quot;,
      &quot;logs&quot;: &quot;firebase functions:log&quot;
    },
    &quot;main&quot;: &quot;lib/index.js&quot;,
    &quot;dependencies&quot;: {
      &quot;@google-cloud/firestore&quot;: &quot;^1.3.0&quot;,
      &quot;@google-cloud/storage&quot;: &quot;^5.1.0&quot;,
      &quot;firebase-admin&quot;: &quot;~7.0.0&quot;,
      &quot;firebase-functions&quot;: &quot;^2.3.1&quot;,
      &quot;guid-typescript&quot;: &quot;^1.0.9&quot;,
      &quot;lint&quot;: &quot;^1.1.2&quot;,
      &quot;request&quot;: &quot;2.88.0&quot;,
      &quot;request-promise&quot;: &quot;4.2.4&quot;,
      &quot;url&quot;: &quot;0.11.0&quot;,
      &quot;uuid&quot;: &quot;3.3.2&quot;
    },
    &quot;devDependencies&quot;: {
      &quot;firebase-functions-test&quot;: &quot;^0.1.6&quot;,
      &quot;tslint&quot;: &quot;^5.12.0&quot;,
      &quot;typescript&quot;: &quot;^3.2.2&quot;
    },
    &quot;private&quot;: true,
    &quot;engines&quot;: {
      &quot;node&quot;: &quot;8&quot;
    }
  }
  </code></pre>
  <p>Many thanks and humble appreciation for reading through.</p>