0

I am trying to catch the update of a document and send a notification to all users but the catch value I'm having trouble parsing it.

in the console.log() this is the catch data:

{ createdAt: Timestamp { _seconds: 1586881980, _nanoseconds: 0 },
  messages: 
   [ { content: 'Un nuevo comienzo para tod@s!\n:)\n\n:-P\n',
       createdAt: [Object],
       displayName: 'Fer...',
       photoUrl: 'https://lh3.googleusercontent.com/...',
       uid: 'IJchaq...' },
     { content: '',
       createdAt: [Object],
       displayName: 'IMP...',
       photoUrl: 'https://lh3.googleusercont...' } 
       ...

and this is my function:

import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
admin.initializeApp();

// const db = admin.firestore();
const fcm = admin.messaging();

export const sendToTopic = functions.firestore
  .document("chats/{chatsId}")
  .onUpdate((change, context) => {

    const newValue = change.after.data();

    // console.log(newValue);

    let latestMessage = newValue.messages[0]; // newValue gives me object is possibly 'undefined'

    const payload: admin.messaging.MessagingPayload = {
      notification: {
        title: "New Message",
        body: latestMessage,
        icon:
          "https://www.dropbox...",
        clickAction: "FLUTTER_NOTIFICATION_CLICK",
      },
    };

    return fcm.sendToTopic("globalChat", payload);
  });

how do I get the latest displayName and the content from the newValue?

Doug Stevenson
  • 236,239
  • 27
  • 275
  • 302
fenchai
  • 164
  • 1
  • 11

2 Answers2

2

I solved it by changing to newValue?messages[0];

fenchai
  • 164
  • 1
  • 11
1

EDIT: Have deleted my previous solution because it introduced new errors as per comments by @fenchai. The crux of the problem is of course dealing with values in typescript, that are possibly null or undefined. Typescript will want you to null check them.

I looked further into this and this SF post had more clarification: https://stackoverflow.com/a/58401023/10303131

As @fenchai notes, you can use the ? operator.

Please read release notes of Typescript, as of late 2019: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html

Items of interest:

Optional Chaining:

// Make x = foo.bar(). If foo null or undefined, x will be undefined.
let x = foo?.bar()

Nullish Coalescing:

// Makes x equal to foo, or if it is null/ undefined, call bar(). 
let x = foo ?? bar();

From a firebase functions point of view, I would still recommend to anyone that they null check important variables before calling further code, as you will have a chance to clarify important errors, as firebase functions may not always tell you which value is undefined and the root cause of the problem.

Example:

const message = myDocument?.data()?.message;
if (message === null || message === undefined){
    console.error("Message is undefined or null");
    // Proceed, or return if message vital to function.  
}
Peter Edwards
  • 106
  • 1
  • 3
  • null checking didn't work and it introduced even more errors :/ unknown display name says: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.ts(2363) and title: says number is not assignable to String | undefined. – fenchai Apr 22 '20 at 15:48
  • looks like adding a ? in front of newValue fixed it. – fenchai Apr 22 '20 at 15:55
  • Thanks, I have edited my solution to be more in line with the problem you were experiencing. – Peter Edwards Apr 23 '20 at 01:38