UNPKG

firebase-admin

Version:
287 lines (286 loc) 13.2 kB
/*! 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;