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;
}