287 lines
13 KiB
JavaScript
287 lines
13 KiB
JavaScript
/*! firebase-admin v14.0.0 */
|
|
"use strict";
|
|
/*!
|
|
* Copyright 2026 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.FirebaseMessagingError = exports.messagingClientErrorCode = exports.MessagingErrorCode = void 0;
|
|
const error_1 = require("../utils/error");
|
|
const deep_copy_1 = require("../utils/deep-copy");
|
|
/**
|
|
* The constant mapping for valid Messaging client error codes.
|
|
*/
|
|
exports.MessagingErrorCode = {
|
|
INVALID_ARGUMENT: 'invalid-argument',
|
|
INVALID_RECIPIENT: 'invalid-recipient',
|
|
INVALID_PAYLOAD: 'invalid-payload',
|
|
INVALID_DATA_PAYLOAD_KEY: 'invalid-data-payload-key',
|
|
PAYLOAD_SIZE_LIMIT_EXCEEDED: 'payload-size-limit-exceeded',
|
|
INVALID_OPTIONS: 'invalid-options',
|
|
INVALID_REGISTRATION_TOKEN: 'invalid-registration-token',
|
|
REGISTRATION_TOKEN_NOT_REGISTERED: 'registration-token-not-registered',
|
|
MISMATCHED_CREDENTIAL: 'mismatched-credential',
|
|
INVALID_PACKAGE_NAME: 'invalid-package-name',
|
|
DEVICE_MESSAGE_RATE_EXCEEDED: 'device-message-rate-exceeded',
|
|
TOPICS_MESSAGE_RATE_EXCEEDED: 'topics-message-rate-exceeded',
|
|
TOPICS_SUBSCRIPTION_RATE_EXCEEDED: 'topics-subscription-rate-exceeded',
|
|
MESSAGE_RATE_EXCEEDED: 'message-rate-exceeded',
|
|
THIRD_PARTY_AUTH_ERROR: 'third-party-auth-error',
|
|
TOO_MANY_TOPICS: 'too-many-topics',
|
|
AUTHENTICATION_ERROR: 'authentication-error',
|
|
SERVER_UNAVAILABLE: 'server-unavailable',
|
|
INTERNAL_ERROR: 'internal-error',
|
|
UNKNOWN_ERROR: 'unknown-error',
|
|
};
|
|
/**
|
|
* Internal Messaging client error code mapping used to construct ErrorInfo.
|
|
*/
|
|
exports.messagingClientErrorCode = {
|
|
INVALID_ARGUMENT: {
|
|
code: exports.MessagingErrorCode.INVALID_ARGUMENT,
|
|
message: 'Invalid argument provided.',
|
|
},
|
|
INVALID_RECIPIENT: {
|
|
code: exports.MessagingErrorCode.INVALID_RECIPIENT,
|
|
message: 'Invalid message recipient provided.',
|
|
},
|
|
INVALID_PAYLOAD: {
|
|
code: exports.MessagingErrorCode.INVALID_PAYLOAD,
|
|
message: 'Invalid message payload provided.',
|
|
},
|
|
INVALID_DATA_PAYLOAD_KEY: {
|
|
code: exports.MessagingErrorCode.INVALID_DATA_PAYLOAD_KEY,
|
|
message: 'The data message payload contains an invalid key. See the reference ' +
|
|
'documentation for the DataMessagePayload type for restricted keys.',
|
|
},
|
|
PAYLOAD_SIZE_LIMIT_EXCEEDED: {
|
|
code: exports.MessagingErrorCode.PAYLOAD_SIZE_LIMIT_EXCEEDED,
|
|
message: 'The provided message payload exceeds the FCM size limits. See the ' +
|
|
'error documentation for more details.',
|
|
},
|
|
INVALID_OPTIONS: {
|
|
code: exports.MessagingErrorCode.INVALID_OPTIONS,
|
|
message: 'Invalid message options provided.',
|
|
},
|
|
INVALID_REGISTRATION_TOKEN: {
|
|
code: exports.MessagingErrorCode.INVALID_REGISTRATION_TOKEN,
|
|
message: 'Invalid registration token provided. Make sure it matches the ' +
|
|
'registration token the client app receives from registering with FCM.',
|
|
},
|
|
REGISTRATION_TOKEN_NOT_REGISTERED: {
|
|
code: exports.MessagingErrorCode.REGISTRATION_TOKEN_NOT_REGISTERED,
|
|
message: 'The provided registration token is not registered. A ' +
|
|
'previously valid registration token can be unregistered for a variety of reasons. See the ' +
|
|
'error documentation for more details. Remove this registration token and stop using it to ' +
|
|
'send messages.',
|
|
},
|
|
MISMATCHED_CREDENTIAL: {
|
|
code: exports.MessagingErrorCode.MISMATCHED_CREDENTIAL,
|
|
message: 'The credential used to authenticate this SDK does not have permission ' +
|
|
'to send messages to the device corresponding to the provided registration token. Make sure the ' +
|
|
'credential and registration token both belong to the same Firebase project.',
|
|
},
|
|
INVALID_PACKAGE_NAME: {
|
|
code: exports.MessagingErrorCode.INVALID_PACKAGE_NAME,
|
|
message: 'The message was addressed to a registration token whose package name does ' +
|
|
'not match the provided "restrictedPackageName" option.',
|
|
},
|
|
DEVICE_MESSAGE_RATE_EXCEEDED: {
|
|
code: exports.MessagingErrorCode.DEVICE_MESSAGE_RATE_EXCEEDED,
|
|
message: 'The rate of messages to a particular device is too high. Reduce ' +
|
|
'the number of messages sent to this device and do not immediately retry sending to this device.',
|
|
},
|
|
TOPICS_MESSAGE_RATE_EXCEEDED: {
|
|
code: exports.MessagingErrorCode.TOPICS_MESSAGE_RATE_EXCEEDED,
|
|
message: 'The rate of messages to subscribers to a particular topic is too ' +
|
|
'high. Reduce the number of messages sent for this topic, and do not immediately retry sending ' +
|
|
'to this topic.',
|
|
},
|
|
TOPICS_SUBSCRIPTION_RATE_EXCEEDED: {
|
|
code: exports.MessagingErrorCode.TOPICS_SUBSCRIPTION_RATE_EXCEEDED,
|
|
message: 'The rate of subscription management requests to a particular topic is too ' +
|
|
'high. Reduce the number of requests sent for this topic, and do not immediately retry the ' +
|
|
'request.',
|
|
},
|
|
MESSAGE_RATE_EXCEEDED: {
|
|
code: exports.MessagingErrorCode.MESSAGE_RATE_EXCEEDED,
|
|
message: 'Sending limit exceeded for the message target.',
|
|
},
|
|
THIRD_PARTY_AUTH_ERROR: {
|
|
code: exports.MessagingErrorCode.THIRD_PARTY_AUTH_ERROR,
|
|
message: 'A message targeted to an iOS device could not be sent because the ' +
|
|
'required APNs SSL certificate was not uploaded or has expired. Check the validity of your ' +
|
|
'development and production certificates.',
|
|
},
|
|
TOO_MANY_TOPICS: {
|
|
code: exports.MessagingErrorCode.TOO_MANY_TOPICS,
|
|
message: 'The maximum number of topics the provided registration token can be ' +
|
|
'subscribed to has been exceeded.',
|
|
},
|
|
AUTHENTICATION_ERROR: {
|
|
code: exports.MessagingErrorCode.AUTHENTICATION_ERROR,
|
|
message: 'An error occurred when trying to authenticate to the FCM servers. Make ' +
|
|
'sure the credential used to authenticate this SDK has the proper permissions. See ' +
|
|
'https://firebase.google.com/docs/admin/setup for setup instructions.',
|
|
},
|
|
SERVER_UNAVAILABLE: {
|
|
code: exports.MessagingErrorCode.SERVER_UNAVAILABLE,
|
|
message: 'The FCM server could not process the request in time. See the error ' +
|
|
'documentation for more details.',
|
|
},
|
|
INTERNAL_ERROR: {
|
|
code: exports.MessagingErrorCode.INTERNAL_ERROR,
|
|
message: 'An internal error has occurred. Please retry the request.',
|
|
},
|
|
UNKNOWN_ERROR: {
|
|
code: exports.MessagingErrorCode.UNKNOWN_ERROR,
|
|
message: 'An unknown server error was returned.',
|
|
},
|
|
};
|
|
/** @const {Record<string, keyof typeof MessagingErrorCode>} Messaging server to client enum error codes. */
|
|
const MESSAGING_SERVER_TO_CLIENT_CODE = {
|
|
/* GENERIC ERRORS */
|
|
// Generic invalid message parameter provided.
|
|
InvalidParameters: 'INVALID_ARGUMENT',
|
|
// Mismatched sender ID.
|
|
MismatchSenderId: 'MISMATCHED_CREDENTIAL',
|
|
// FCM server unavailable.
|
|
Unavailable: 'SERVER_UNAVAILABLE',
|
|
// FCM server internal error.
|
|
InternalServerError: 'INTERNAL_ERROR',
|
|
/* SEND ERRORS */
|
|
// Invalid registration token format.
|
|
InvalidRegistration: 'INVALID_REGISTRATION_TOKEN',
|
|
// Registration token is not registered.
|
|
NotRegistered: 'REGISTRATION_TOKEN_NOT_REGISTERED',
|
|
// Registration token does not match restricted package name.
|
|
InvalidPackageName: 'INVALID_PACKAGE_NAME',
|
|
// Message payload size limit exceeded.
|
|
MessageTooBig: 'PAYLOAD_SIZE_LIMIT_EXCEEDED',
|
|
// Invalid key in the data message payload.
|
|
InvalidDataKey: 'INVALID_DATA_PAYLOAD_KEY',
|
|
// Invalid time to live option.
|
|
InvalidTtl: 'INVALID_OPTIONS',
|
|
// Device message rate exceeded.
|
|
DeviceMessageRateExceeded: 'DEVICE_MESSAGE_RATE_EXCEEDED',
|
|
// Topics message rate exceeded.
|
|
TopicsMessageRateExceeded: 'TOPICS_MESSAGE_RATE_EXCEEDED',
|
|
// Invalid APNs credentials.
|
|
InvalidApnsCredential: 'THIRD_PARTY_AUTH_ERROR',
|
|
/* FCM v1 canonical error codes */
|
|
NOT_FOUND: 'REGISTRATION_TOKEN_NOT_REGISTERED',
|
|
PERMISSION_DENIED: 'MISMATCHED_CREDENTIAL',
|
|
RESOURCE_EXHAUSTED: 'MESSAGE_RATE_EXCEEDED',
|
|
UNAUTHENTICATED: 'THIRD_PARTY_AUTH_ERROR',
|
|
/* FCM v1 new error codes */
|
|
APNS_AUTH_ERROR: 'THIRD_PARTY_AUTH_ERROR',
|
|
INTERNAL: 'INTERNAL_ERROR',
|
|
INVALID_ARGUMENT: 'INVALID_ARGUMENT',
|
|
QUOTA_EXCEEDED: 'MESSAGE_RATE_EXCEEDED',
|
|
SENDER_ID_MISMATCH: 'MISMATCHED_CREDENTIAL',
|
|
THIRD_PARTY_AUTH_ERROR: 'THIRD_PARTY_AUTH_ERROR',
|
|
UNAVAILABLE: 'SERVER_UNAVAILABLE',
|
|
UNREGISTERED: 'REGISTRATION_TOKEN_NOT_REGISTERED',
|
|
UNSPECIFIED_ERROR: 'UNKNOWN_ERROR',
|
|
};
|
|
/**
|
|
* @const {Record<string, keyof typeof MessagingErrorCode>} Topic management (IID)
|
|
* server to client enum error codes.
|
|
*/
|
|
const TOPIC_MGT_SERVER_TO_CLIENT_CODE = {
|
|
/* TOPIC SUBSCRIPTION MANAGEMENT ERRORS */
|
|
NOT_FOUND: 'REGISTRATION_TOKEN_NOT_REGISTERED',
|
|
INVALID_ARGUMENT: 'INVALID_REGISTRATION_TOKEN',
|
|
TOO_MANY_TOPICS: 'TOO_MANY_TOPICS',
|
|
RESOURCE_EXHAUSTED: 'TOPICS_SUBSCRIPTION_RATE_EXCEEDED',
|
|
PERMISSION_DENIED: 'AUTHENTICATION_ERROR',
|
|
DEADLINE_EXCEEDED: 'SERVER_UNAVAILABLE',
|
|
INTERNAL: 'INTERNAL_ERROR',
|
|
UNKNOWN: 'UNKNOWN_ERROR',
|
|
};
|
|
/**
|
|
* Firebase Messaging error code structure. This extends `FirebaseError`.
|
|
*/
|
|
class FirebaseMessagingError extends error_1.FirebaseError {
|
|
/**
|
|
* Creates the developer-facing error corresponding to the backend error code.
|
|
*
|
|
* @param serverErrorCode - The server error code.
|
|
* @param [message] The error message. The default message is used
|
|
* if not provided.
|
|
* @param [serverError] The error's raw server response.
|
|
* @returns The corresponding developer-facing error.
|
|
* @internal
|
|
*/
|
|
static fromServerError(serverErrorCode, message, serverError) {
|
|
// If not found, default to unknown error.
|
|
let clientCodeKey = 'UNKNOWN_ERROR';
|
|
if (serverErrorCode && serverErrorCode in MESSAGING_SERVER_TO_CLIENT_CODE) {
|
|
clientCodeKey = MESSAGING_SERVER_TO_CLIENT_CODE[serverErrorCode];
|
|
}
|
|
const error = (0, deep_copy_1.deepCopy)(exports.messagingClientErrorCode[clientCodeKey]);
|
|
error.message = message || error.message;
|
|
const rawData = serverError?.response?.data;
|
|
if (clientCodeKey === 'UNKNOWN_ERROR' && typeof rawData !== 'undefined') {
|
|
try {
|
|
error.message += ` Raw server response: "${typeof rawData === 'string' ? rawData : JSON.stringify(rawData)}"`;
|
|
}
|
|
catch (e) {
|
|
// Ignore JSON parsing error.
|
|
}
|
|
}
|
|
error.cause = serverError;
|
|
error.httpResponse = serverError?.response ? (0, error_1.toHttpResponse)(serverError.response) : undefined;
|
|
return new FirebaseMessagingError(error);
|
|
}
|
|
/**
|
|
* @internal
|
|
*/
|
|
static fromTopicManagementServerError(serverErrorCode, message, serverError) {
|
|
// If not found, default to unknown error.
|
|
const clientCodeKey = TOPIC_MGT_SERVER_TO_CLIENT_CODE[serverErrorCode] || 'UNKNOWN_ERROR';
|
|
const error = (0, deep_copy_1.deepCopy)(exports.messagingClientErrorCode[clientCodeKey]);
|
|
error.message = message || error.message;
|
|
const rawData = serverError?.response?.data;
|
|
if (clientCodeKey === 'UNKNOWN_ERROR' && typeof rawData !== 'undefined') {
|
|
try {
|
|
error.message += ` Raw server response: "${typeof rawData === 'string' ? rawData : JSON.stringify(rawData)}"`;
|
|
}
|
|
catch (e) {
|
|
// Ignore JSON parsing error.
|
|
}
|
|
}
|
|
error.cause = serverError;
|
|
error.httpResponse = serverError?.response ? (0, error_1.toHttpResponse)(serverError.response) : undefined;
|
|
return new FirebaseMessagingError(error);
|
|
}
|
|
/**
|
|
*
|
|
* @param info - The error code info.
|
|
* @param message - The error message. This will override the default message if provided.
|
|
*/
|
|
constructor(info, message) {
|
|
// Override default message if custom message provided.
|
|
super({
|
|
code: `messaging/${info.code}`,
|
|
message: message || info.message,
|
|
httpResponse: info.httpResponse,
|
|
cause: info.cause,
|
|
});
|
|
/** @internal */
|
|
this.codePrefix = 'messaging';
|
|
}
|
|
}
|
|
exports.FirebaseMessagingError = FirebaseMessagingError;
|