Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
80 changes: 57 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,83 @@ 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`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Maybe clarify that tokens take precedence if both are provided.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, added!

* If both `tokens` and `fids` are provided, `tokens` are processed first, followed by `fids`.
* 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