I want to send a PushNotification via Cloud Messaging when a document is added inside a collection of a user called notifications. I am saving the token for the user as suggested in the docs in a arrayUnion in a field called messagingTokens.
Additionally the notification should only be sent if a field called isPushEnabled is true. With this information I build this cloud function and successfully deployed it:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const { onDocumentCreated } = require("firebase-functions/v2/firestore");
const { setGlobalOptions } = require("firebase-functions/v2");
admin.initializeApp();
// Set the maximum instances to 10 for all functions
setGlobalOptions({ maxInstances: 10 });
const notificationPath = "allUsers/{userId}/notifications/{notificationId}";
exports.sendNotification = onDocumentCreated(notificationPath, async (event) => {
    functions.logger.log("New notificatin document was created"); 
    const data = event.data.after.data();
    const senderUid = data.senderUid;
    const receiverUid = data.receiverUid;
    const notificationOption = data.option;
    functions.logger.log("Retrieved notification fields"); 
    if (notificationOption === "receivedFriendRequest") {
        functions.logger.log("Is option: receivedFriendRequest");
        await onSentFriendRequest(senderUid, receiverUid);
    }
});
async function onSentFriendRequest(ownerId, userId) {
    // Get the owners details
    const owner = await admin.firestore().collection("allUsers").doc(ownerId).get();
    // Get the users details
    const user = await admin.firestore().collection("allUsers").doc(userId).get();
    const userHasNotificationsEnabled = user.data().isPushEnabled;
    functions.logger.log("If this does not print, then your function is not being called");
    if (!userHasNotificationsEnabled) {
        functions.logger.log("User does not have push enabled");
        return;
    }
    functions.logger.log("User has push enabled");
    // Listing all tokens as an array.
    tokens = user.data().messagingTokens;
    // Send message to all tokens
    const response = await admin.messaging().sendEachForMulticast({
        tokens: tokens,
        notification: {
            title: "Neue Freundschaftsanfrage",
            body: `${owner.data().username} möchte mit dir befreundet sein.`,
        },
        data: {
            ownerId: ownerId,
            userId: userId,
            notificationOption: "receivedFriendRequest",
        },
    });
    // For each message check if there was an error.
    const tokensToRemove = [];
    response.results.forEach((result, index) => {
        const error = result.error;
        if (error) {
            functions.logger.error(
                'Failure sending notification to',
                tokens[index],
                error
            );
            // Cleanup the tokens who are not registered anymore.
            if (error.code === 'messaging/invalid-registration-token' ||
                error.code === 'messaging/registration-token-not-registered') {
                tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
            }
        }
    });
    return Promise.all(tokensToRemove);
}
Like I said, the deployment was successful. But when a document is added to the notifications-collection I get this from my logs:

Inside the Firebase-Console I see that the function was triggered, I get a TypeError.
What am I doing wrong here? Let me know if you need more information.
EDIT
I had an error about maxScale which I could fix by adding this line inside my index.js-file:
    setGlobalOptions({maxInstances: 10})
and this inside my firebase.json:
  "frameworksBackend": {
    "region": "us-central1",
    "maxInstances": 10
  }
                I got it working. I had smaller issues in my code, like Typos, or the suggested improvements from the answers.
By following this Sample-Code and also looking into doc for sendEachForMultiCast and onDocumentCreated I was able to make it work with this code:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const { onDocumentCreated } = require("firebase-functions/v2/firestore");
const { setGlobalOptions } = require("firebase-functions/v2");
admin.initializeApp();
// Set the maximum instances to 10 for all functions
setGlobalOptions({ maxInstances: 10 });
const notificationPath = "allUsers/{userId}/notifications/{notificationId}";
exports.sendNotification = onDocumentCreated(notificationPath, async (event) => {
    functions.logger.log("New notificatin document was created");
    const snapshot = event.data;
    if (!snapshot) {
        console.log("No data associated with the event");
        return;
    }
    const data = snapshot.data();
    // access a particular field as you would any JS property
    const name = data.name;
    const senderUid = data.senderUid;
    const receiverUid = data.receiverUid;
    const notificationOption = data.option;
    if (notificationOption === "recievedFriendRequest") {
        await onSentFriendRequest(senderUid, receiverUid);
    } else {
        functions.logger.log(`is notificationOption: ${notificationOption}`);
    }
});
async function onSentFriendRequest(ownerId, userId) {
    // Get the owners details
    const owner = await admin.firestore().collection("allUsers").doc(ownerId).get();
    // Get the users details
    const user = await admin.firestore().collection("allUsers").doc(userId).get();
    const userHasNotificationsEnabled = user.data().isPushEnabled;
    if (!userHasNotificationsEnabled) {
        functions.logger.log("User does not have push enabled");
        return;
    }
 
    // Listing all tokens as an array.
    tokens = user.data().messagingTokens;
    // Send message to all tokens
    const response = await admin.messaging().sendEachForMulticast({
        tokens: tokens,
        notification: {
            title: "Neue Freundschaftsanfrage",
            body: `${owner.data().username} möchte mit dir befreundet sein.`,
        },
        data: {
            ownerId: ownerId,
            userId: userId,
            notificationOption: "receivedFriendRequest",
        },
    });
    functions.logger.log("Successflully send Notification");
    // For each message check if there was an error.
    const tokensToRemove = [];
    response.responses.forEach((result, index) => {
        const error = result.error;
        if (error) {
            functions.logger.error(
                'Failure sending notification to',
                tokens[index],
                error
            );
            // Cleanup the tokens who are not registered anymore.
            if (error.code === 'messaging/unregistered' || 
                error.code === 'messaging/invalid-argument') {               
                tokensToRemove.push(admin.firestore().collection("allUsers").doc(userId).update({
                    "messagingTokens": admin.firestore.FieldValue.arrayRemove(tokens[index])
                }));
            }
        }
    });
    return Promise.all(tokensToRemove);
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With