private validateMessagingPayload()

in src/messaging/messaging.ts [786:867]


  private validateMessagingPayload(payload: MessagingPayload): MessagingPayload {
    const payloadCopy: MessagingPayload = deepCopy(payload);

    const payloadKeys = Object.keys(payloadCopy);
    const validPayloadKeys = ['data', 'notification'];

    let containsDataOrNotificationKey = false;
    payloadKeys.forEach((payloadKey) => {
      // Validate the payload does not contain any invalid keys
      if (validPayloadKeys.indexOf(payloadKey) === -1) {
        throw new FirebaseMessagingError(
          MessagingClientErrorCode.INVALID_PAYLOAD,
          `Messaging payload contains an invalid "${payloadKey}" property. Valid properties are ` +
          '"data" and "notification".',
        );
      } else {
        containsDataOrNotificationKey = true;
      }
    });

    // Validate the payload contains at least one of the "data" and "notification" keys
    if (!containsDataOrNotificationKey) {
      throw new FirebaseMessagingError(
        MessagingClientErrorCode.INVALID_PAYLOAD,
        'Messaging payload must contain at least one of the "data" or "notification" properties.',
      );
    }

    const validatePayload = (payloadKey: string, value: DataMessagePayload | NotificationMessagePayload): void => {
      // Validate each top-level key in the payload is an object
      if (!validator.isNonNullObject(value)) {
        throw new FirebaseMessagingError(
          MessagingClientErrorCode.INVALID_PAYLOAD,
          `Messaging payload contains an invalid value for the "${payloadKey}" property. ` +
          'Value must be an object.',
        );
      }

      Object.keys(value).forEach((subKey) => {
        if (!validator.isString(value[subKey])) {
          // Validate all sub-keys have a string value
          throw new FirebaseMessagingError(
            MessagingClientErrorCode.INVALID_PAYLOAD,
            `Messaging payload contains an invalid value for the "${payloadKey}.${subKey}" ` +
            'property. Values must be strings.',
          );
        } else if (payloadKey === 'data' && /^google\./.test(subKey)) {
          // Validate the data payload does not contain keys which start with 'google.'.
          throw new FirebaseMessagingError(
            MessagingClientErrorCode.INVALID_PAYLOAD,
            `Messaging payload contains the blacklisted "data.${subKey}" property.`,
          );
        }
      });
    };

    if (payloadCopy.data !== undefined) {
      validatePayload('data', payloadCopy.data);
    }
    if (payloadCopy.notification !== undefined) {
      validatePayload('notification', payloadCopy.notification);
    }

    // Validate the data payload object does not contain blacklisted properties
    if ('data' in payloadCopy) {
      BLACKLISTED_DATA_PAYLOAD_KEYS.forEach((blacklistedKey) => {
        if (blacklistedKey in payloadCopy.data!) {
          throw new FirebaseMessagingError(
            MessagingClientErrorCode.INVALID_PAYLOAD,
            `Messaging payload contains the blacklisted "data.${blacklistedKey}" property.`,
          );
        }
      });
    }

    // Convert whitelisted camelCase keys to underscore_case
    if (payloadCopy.notification) {
      utils.renameProperties(payloadCopy.notification, CAMELCASED_NOTIFICATION_PAYLOAD_KEYS_MAP);
    }

    return payloadCopy;
  }