Skip to content
Open
8 changes: 8 additions & 0 deletions etc/firebase-admin.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,10 @@ export namespace messaging {
export type DataMessagePayload = DataMessagePayload;
// Warning: (ae-forgotten-export) The symbol "FcmOptions" needs to be exported by the entry point default-namespace.d.ts
export type FcmOptions = FcmOptions;
// Warning: (ae-forgotten-export) The symbol "FidMessage" needs to be exported by the entry point default-namespace.d.ts
export type FidMessage = FidMessage;
// Warning: (ae-forgotten-export) The symbol "FidMulticastMessage" needs to be exported by the entry point default-namespace.d.ts
export type FidMulticastMessage = FidMulticastMessage;
// Warning: (ae-forgotten-export) The symbol "LightSettings" needs to be exported by the entry point default-namespace.d.ts
export type LightSettings = LightSettings;
// Warning: (ae-forgotten-export) The symbol "Message" needs to be exported by the entry point default-namespace.d.ts
Expand All @@ -387,6 +391,8 @@ export namespace messaging {
// Warning: (ae-forgotten-export) The symbol "MessagingTopicManagementResponse" needs to be exported by the entry point default-namespace.d.ts
export type MessagingTopicManagementResponse = MessagingTopicManagementResponse;
// Warning: (ae-forgotten-export) The symbol "MulticastMessage" needs to be exported by the entry point default-namespace.d.ts
//
// @deprecated
export type MulticastMessage = MulticastMessage;
// Warning: (ae-forgotten-export) The symbol "Notification" needs to be exported by the entry point default-namespace.d.ts
export type Notification = Notification;
Expand All @@ -395,6 +401,8 @@ export namespace messaging {
// Warning: (ae-forgotten-export) The symbol "SendResponse" needs to be exported by the entry point default-namespace.d.ts
export type SendResponse = SendResponse;
// Warning: (ae-forgotten-export) The symbol "TokenMessage" needs to be exported by the entry point default-namespace.d.ts
//
// @deprecated
export type TokenMessage = TokenMessage;
// Warning: (ae-forgotten-export) The symbol "TopicMessage" needs to be exported by the entry point default-namespace.d.ts
export type TopicMessage = TopicMessage;
Expand Down
21 changes: 17 additions & 4 deletions etc/firebase-admin.messaging.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,16 @@ export interface FcmOptions {
analyticsLabel?: string;
}

// @public
export interface FidMessage extends BaseMessage {
fid: string;
}

// @public
export interface FidMulticastMessage extends BaseMessage {
fids: string[];
}

// Warning: (ae-forgotten-export) The symbol "PrefixedFirebaseError" needs to be exported by the entry point index.d.ts
//
// @public
Expand All @@ -187,7 +197,7 @@ export interface LightSettings {
}

// @public
export type Message = TokenMessage | TopicMessage | ConditionMessage;
export type Message = FidMessage | TokenMessage | TopicMessage | ConditionMessage;

// @public
export class Messaging {
Expand All @@ -196,7 +206,9 @@ export class Messaging {
enableLegacyHttpTransport(): void;
send(message: Message, dryRun?: boolean): Promise<string>;
sendEach(messages: Message[], dryRun?: boolean): Promise<BatchResponse>;
// @deprecated
sendEachForMulticast(message: MulticastMessage, dryRun?: boolean): Promise<BatchResponse>;
sendEachForMulticast(message: FidMulticastMessage, dryRun?: boolean): Promise<BatchResponse>;
subscribeToTopic(registrationTokenOrTokens: string | string[], topic: string): Promise<MessagingTopicManagementResponse>;
unsubscribeFromTopic(registrationTokenOrTokens: string | string[], topic: string): Promise<MessagingTopicManagementResponse>;
}
Expand Down Expand Up @@ -327,9 +339,10 @@ export interface MessagingTopicManagementResponse {
successCount: number;
}

// @public
// @public @deprecated
export interface MulticastMessage extends BaseMessage {
// (undocumented)
fids?: string[];
// @deprecated
tokens: string[];
}

Expand Down Expand Up @@ -366,7 +379,7 @@ export interface SendResponse {
success: boolean;
}

// @public (undocumented)
// @public @deprecated (undocumented)
export interface TokenMessage extends BaseMessage {
// (undocumented)
token: string;
Expand Down
2 changes: 2 additions & 0 deletions src/messaging/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ export {
CriticalSound,
ConditionMessage,
FcmOptions,
FidMessage,
FidMulticastMessage,
LightSettings,
Message,
MessagingTopicManagementResponse,
Expand Down
43 changes: 38 additions & 5 deletions src/messaging/messaging-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@ export interface BaseMessage {
fcmOptions?: FcmOptions;
}

/**
* Interface representing a message that targets a Firebase Installation ID (FID).
*/
export interface FidMessage extends BaseMessage {
/**
* The Firebase Installation ID (FID) to which the message should be sent.
*/
fid: string;
}
Comment thread
yvonnep165 marked this conversation as resolved.

/**
* @deprecated Use {@link FidMessage} instead.
*/
export interface TokenMessage extends BaseMessage {
token: string;
}
Expand All @@ -40,18 +53,38 @@ export interface ConditionMessage extends BaseMessage {

/**
* Payload for the {@link Messaging.send} operation. The payload contains all the fields
* in the BaseMessage type, and exactly one of token, topic or condition.
* in the BaseMessage type, and exactly one of fid, token, topic or condition.
*/
export type Message = TokenMessage | TopicMessage | ConditionMessage;
export type Message = FidMessage | TokenMessage | TopicMessage | ConditionMessage;

/**
* Payload for the {@link Messaging.sendEachForMulticast} method. The payload contains all the fields
* in the BaseMessage type, and a list of tokens.
* Payload for the `sendEachForMulticast` method.
*
* @deprecated Use {@link FidMulticastMessage} instead.
*/
export interface MulticastMessage extends BaseMessage {
/**
* A list of Firebase Installation IDs (FIDs) to target.
*/
fids?: string[];
/**
* A list of registration tokens to target.
*
* @deprecated Use `fids` in {@link FidMulticastMessage} instead.
*/
tokens: string[];
}

/**
* Payload for the `sendEachForMulticast` method containing only FIDs.
*/
export interface FidMulticastMessage extends BaseMessage {
/**
* A list of Firebase Installation IDs (FIDs) to target.
*/
fids: string[];
}
Comment thread
yvonnep165 marked this conversation as resolved.

/**
* A notification that can be included in {@link Message}.
*/
Expand Down Expand Up @@ -1001,7 +1034,7 @@ export interface MessagingTopicManagementResponse {

/**
* Interface representing the server response from the
* {@link Messaging.sendEach} and {@link Messaging.sendEachForMulticast} methods.
* {@link Messaging.sendEach} and `sendEachForMulticast` methods.
*/
export interface BatchResponse {

Expand Down
4 changes: 2 additions & 2 deletions src/messaging/messaging-internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ export function validateMessage(message: Message): void {
}
}

const targets = [anyMessage.token, anyMessage.topic, anyMessage.condition];
const targets = [anyMessage.fid, anyMessage.token, anyMessage.topic, anyMessage.condition];
if (targets.filter((v) => validator.isNonEmptyString(v)).length !== 1) {
throw new FirebaseMessagingError(
MessagingClientErrorCode.INVALID_PAYLOAD,
'Exactly one of topic, token or condition is required');
'Exactly one of fid, topic, token or condition is required');
}

validateStringMap(message.data, 'data');
Expand Down
16 changes: 16 additions & 0 deletions src/messaging/messaging-namespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import {
CriticalSound as TCriticalSound,
ConditionMessage as TConditionMessage,
FcmOptions as TFcmOptions,
FidMessage as TFidMessage,
FidMulticastMessage as TFidMulticastMessage,
LightSettings as TLightSettings,
Message as TMessage,
MessagingTopicManagementResponse as TMessagingTopicManagementResponse,
Expand Down Expand Up @@ -161,9 +163,16 @@ export namespace messaging {

/**
* Type alias to {@link firebase-admin.messaging#MulticastMessage}.
*
* @deprecated Use {@link firebase-admin.messaging#FidMulticastMessage} instead.
*/
export type MulticastMessage = TMulticastMessage;

/**
* Type alias to {@link firebase-admin.messaging#FidMulticastMessage}.
*/
export type FidMulticastMessage = TFidMulticastMessage;

/**
* Type alias to {@link firebase-admin.messaging#Notification}.
*/
Expand All @@ -174,8 +183,15 @@ export namespace messaging {
*/
export type SendResponse = TSendResponse;

/**
* Type alias to {@link firebase-admin.messaging#FidMessage}.
*/
export type FidMessage = TFidMessage;

/**
* Type alias to {@link firebase-admin.messaging#TokenMessage}.
*
* @deprecated Use {@link firebase-admin.messaging#FidMessage} instead.
*/
export type TokenMessage = TTokenMessage;

Expand Down
79 changes: 56 additions & 23 deletions src/messaging/messaging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { FirebaseMessagingRequestHandler } from './messaging-api-request-interna

import {
BatchResponse,
FidMulticastMessage,
Message,
MessagingTopicManagementResponse,
MulticastMessage,
Expand Down Expand Up @@ -274,50 +275,82 @@ export class Messaging {
}

/**
* Sends the given multicast message to all the FCM registration tokens
* Sends the given multicast message to all the FCM registration tokens or fids
* specified in it.
*
* This method uses the {@link Messaging.sendEach} API under the hood to send the given
* message to all the target recipients. The responses list obtained from the
* return value corresponds to the order of tokens in the `MulticastMessage`.
* return value corresponds to the order of tokens/fids in the `MulticastMessage`.
* An error from this method or a `BatchResponse` with all failures indicates a total
* failure, meaning that the messages in the list could be sent. Partial failures or
* failures are only indicated by a `BatchResponse` return value.
* failure, meaning that the messages in the list could not be sent. Partial failures
* are only indicated by a `BatchResponse` return value.
*
* @param message - A multicast message
* containing up to 500 tokens.
* @deprecated Use the overload accepting {@link FidMulticastMessage} instead.
*
* @param message - A multicast message containing up to 500 tokens and/or fids.
* @param dryRun - Whether to send the message in the dry-run
* (validation only) mode.
* @returns A Promise fulfilled with an object representing the result of the
* send operation.
*/
public sendEachForMulticast(message: MulticastMessage, dryRun?: boolean): Promise<BatchResponse> {
const copy: MulticastMessage = deepCopy(message);
public sendEachForMulticast(message: MulticastMessage, dryRun?: boolean): Promise<BatchResponse>;

/**
* Sends the given multicast message to all the FCM fids specified in it.
*
* This method uses the {@link Messaging.sendEach} API under the hood to send the given
* message to all the target recipients. The responses list obtained from the
* return value corresponds to the order of fids in the `FidMulticastMessage`.
* An error from this method or a `BatchResponse` with all failures indicates a total
* failure, meaning that the messages in the list could not be sent. Partial failures
* are only indicated by a `BatchResponse` return value.
*
* @param message - A multicast message containing up to 500 fids.
* @param dryRun - Whether to send the message in the dry-run (validation only) mode.
* @returns A Promise fulfilled with an object representing the result of the send operation.
*/
public sendEachForMulticast(message: FidMulticastMessage, dryRun?: boolean): Promise<BatchResponse>;

public sendEachForMulticast(
message: MulticastMessage | FidMulticastMessage,
dryRun?: boolean,
): Promise<BatchResponse> {
const copy: any = deepCopy(message);
if (!validator.isNonNullObject(copy)) {
throw new FirebaseMessagingError(
MessagingClientErrorCode.INVALID_ARGUMENT, 'MulticastMessage must be a non-null object');
}
if (!validator.isNonEmptyArray(copy.tokens)) {

const { tokens, fids, ...baseMessage } = copy;

const tokenList: string[] = tokens || [];
const fidList: string[] = fids || [];

if ('tokens' in copy && !validator.isArray(copy.tokens)) {
throw new FirebaseMessagingError(
MessagingClientErrorCode.INVALID_ARGUMENT, 'tokens must be a valid array');
}
if ('fids' in copy && !validator.isArray(copy.fids)) {
throw new FirebaseMessagingError(
MessagingClientErrorCode.INVALID_ARGUMENT, 'tokens must be a non-empty array');
MessagingClientErrorCode.INVALID_ARGUMENT, 'fids must be a valid array');
}
if (copy.tokens.length > FCM_MAX_BATCH_SIZE) {
if (tokenList.length === 0 && fidList.length === 0) {
throw new FirebaseMessagingError(
MessagingClientErrorCode.INVALID_ARGUMENT, 'Either tokens or fids must be a non-empty array');
}

const totalLength = tokenList.length + fidList.length;
if (totalLength > FCM_MAX_BATCH_SIZE) {
throw new FirebaseMessagingError(
MessagingClientErrorCode.INVALID_ARGUMENT,
`tokens list must not contain more than ${FCM_MAX_BATCH_SIZE} items`);
`The total number of tokens and fids must not exceed ${FCM_MAX_BATCH_SIZE}.`);
}

const messages: Message[] = copy.tokens.map((token) => {
return {
token,
android: copy.android,
apns: copy.apns,
data: copy.data,
notification: copy.notification,
webpush: copy.webpush,
fcmOptions: copy.fcmOptions,
};
});
const messages: Message[] = [
...tokenList.map((token) => ({ ...baseMessage, token } as Message)),
...fidList.map((fid) => ({ ...baseMessage, fid } as Message)),
];

return this.sendEach(messages, dryRun);
}

Expand Down
Loading
Loading