@@ -39,6 +39,7 @@ import {
39
39
MessagingConditionResponse ,
40
40
DataMessagePayload ,
41
41
NotificationMessagePayload ,
42
+ SendResponse ,
42
43
} from './messaging-api' ;
43
44
44
45
// FCM endpoints
@@ -250,6 +251,124 @@ export class Messaging {
250
251
} ) ;
251
252
}
252
253
254
+ /**
255
+ * Sends each message in the given array via Firebase Cloud Messaging.
256
+ *
257
+ * Unlike {@link Messaging.sendAll}, this method makes a single RPC call for each message
258
+ * in the given array.
259
+ *
260
+ * The responses list obtained from the return value corresponds to the order of `messages`.
261
+ * An error from this method or a `BatchResponse` with all failures indicates a total failure,
262
+ * meaning that none of the messages in the list could be sent. Partial failures or no
263
+ * failures are only indicated by a `BatchResponse` return value.
264
+ *
265
+ * @param messages - A non-empty array
266
+ * containing up to 500 messages.
267
+ * @param dryRun - Whether to send the messages in the dry-run
268
+ * (validation only) mode.
269
+ * @returns A Promise fulfilled with an object representing the result of the
270
+ * send operation.
271
+ */
272
+ public sendEach ( messages : Message [ ] , dryRun ?: boolean ) : Promise < BatchResponse > {
273
+ if ( validator . isArray ( messages ) && messages . constructor !== Array ) {
274
+ // In more recent JS specs, an array-like object might have a constructor that is not of
275
+ // Array type. Our deepCopy() method doesn't handle them properly. Convert such objects to
276
+ // a regular array here before calling deepCopy(). See issue #566 for details.
277
+ messages = Array . from ( messages ) ;
278
+ }
279
+
280
+ const copy : Message [ ] = deepCopy ( messages ) ;
281
+ if ( ! validator . isNonEmptyArray ( copy ) ) {
282
+ throw new FirebaseMessagingError (
283
+ MessagingClientErrorCode . INVALID_ARGUMENT , 'messages must be a non-empty array' ) ;
284
+ }
285
+ if ( copy . length > FCM_MAX_BATCH_SIZE ) {
286
+ throw new FirebaseMessagingError (
287
+ MessagingClientErrorCode . INVALID_ARGUMENT ,
288
+ `messages list must not contain more than ${ FCM_MAX_BATCH_SIZE } items` ) ;
289
+ }
290
+ if ( typeof dryRun !== 'undefined' && ! validator . isBoolean ( dryRun ) ) {
291
+ throw new FirebaseMessagingError (
292
+ MessagingClientErrorCode . INVALID_ARGUMENT , 'dryRun must be a boolean' ) ;
293
+ }
294
+
295
+ return this . getUrlPath ( )
296
+ . then ( ( urlPath ) => {
297
+ const requests : Promise < SendResponse > [ ] = copy . map ( ( message ) => {
298
+ validateMessage ( message ) ;
299
+ const request : { message : Message ; validate_only ?: boolean } = { message } ;
300
+ if ( dryRun ) {
301
+ request . validate_only = true ;
302
+ }
303
+ return this . messagingRequestHandler . invokeRequestHandlerForSendResponse ( FCM_SEND_HOST , urlPath , request ) ;
304
+ } ) ;
305
+ return Promise . allSettled ( requests ) ;
306
+ } ) . then ( ( results ) => {
307
+ const responses : SendResponse [ ] = [ ] ;
308
+ results . forEach ( result => {
309
+ if ( result . status === 'fulfilled' ) {
310
+ responses . push ( result . value ) ;
311
+ } else { // rejected
312
+ responses . push ( { success : false , error : result . reason } )
313
+ }
314
+ } )
315
+ const successCount : number = responses . filter ( ( resp ) => resp . success ) . length ;
316
+ return {
317
+ responses,
318
+ successCount,
319
+ failureCount : responses . length - successCount ,
320
+ } ;
321
+ } ) ;
322
+ }
323
+
324
+ /**
325
+ * Sends the given multicast message to all the FCM registration tokens
326
+ * specified in it.
327
+ *
328
+ * This method uses the {@link Messaging.sendEach} API under the hood to send the given
329
+ * message to all the target recipients. The responses list obtained from the
330
+ * return value corresponds to the order of tokens in the `MulticastMessage`.
331
+ * An error from this method or a `BatchResponse` with all failures indicates a total
332
+ * failure, meaning that the messages in the list could be sent. Partial failures or
333
+ * failures are only indicated by a `BatchResponse` return value.
334
+ *
335
+ * @param message - A multicast message
336
+ * containing up to 500 tokens.
337
+ * @param dryRun - Whether to send the message in the dry-run
338
+ * (validation only) mode.
339
+ * @returns A Promise fulfilled with an object representing the result of the
340
+ * send operation.
341
+ */
342
+ public sendEachForMulticast ( message : MulticastMessage , dryRun ?: boolean ) : Promise < BatchResponse > {
343
+ const copy : MulticastMessage = deepCopy ( message ) ;
344
+ if ( ! validator . isNonNullObject ( copy ) ) {
345
+ throw new FirebaseMessagingError (
346
+ MessagingClientErrorCode . INVALID_ARGUMENT , 'MulticastMessage must be a non-null object' ) ;
347
+ }
348
+ if ( ! validator . isNonEmptyArray ( copy . tokens ) ) {
349
+ throw new FirebaseMessagingError (
350
+ MessagingClientErrorCode . INVALID_ARGUMENT , 'tokens must be a non-empty array' ) ;
351
+ }
352
+ if ( copy . tokens . length > FCM_MAX_BATCH_SIZE ) {
353
+ throw new FirebaseMessagingError (
354
+ MessagingClientErrorCode . INVALID_ARGUMENT ,
355
+ `tokens list must not contain more than ${ FCM_MAX_BATCH_SIZE } items` ) ;
356
+ }
357
+
358
+ const messages : Message [ ] = copy . tokens . map ( ( token ) => {
359
+ return {
360
+ token,
361
+ android : copy . android ,
362
+ apns : copy . apns ,
363
+ data : copy . data ,
364
+ notification : copy . notification ,
365
+ webpush : copy . webpush ,
366
+ fcmOptions : copy . fcmOptions ,
367
+ } ;
368
+ } ) ;
369
+ return this . sendEach ( messages , dryRun ) ;
370
+ }
371
+
253
372
/**
254
373
* Sends all the messages in the given array via Firebase Cloud Messaging.
255
374
* Employs batching to send the entire list as a single RPC call. Compared
@@ -258,8 +377,8 @@ export class Messaging {
258
377
*
259
378
* The responses list obtained from the return value
260
379
* corresponds to the order of tokens in the `MulticastMessage`. An error
261
- * from this method indicates a total failure -- i.e. none of the messages in
262
- * the list could be sent. Partial failures are indicated by a `BatchResponse`
380
+ * from this method indicates a total failure, meaning that none of the messages
381
+ * in the list could be sent. Partial failures are indicated by a `BatchResponse`
263
382
* return value.
264
383
*
265
384
* @param messages - A non-empty array
@@ -268,6 +387,8 @@ export class Messaging {
268
387
* (validation only) mode.
269
388
* @returns A Promise fulfilled with an object representing the result of the
270
389
* send operation.
390
+ *
391
+ * @deprecated Use {@link Messaging.sendEach} instead.
271
392
*/
272
393
public sendAll ( messages : Message [ ] , dryRun ?: boolean ) : Promise < BatchResponse > {
273
394
if ( validator . isArray ( messages ) && messages . constructor !== Array ) {
@@ -316,16 +437,18 @@ export class Messaging {
316
437
* This method uses the `sendAll()` API under the hood to send the given
317
438
* message to all the target recipients. The responses list obtained from the
318
439
* return value corresponds to the order of tokens in the `MulticastMessage`.
319
- * An error from this method indicates a total failure -- i.e. the message was
320
- * not sent to any of the tokens in the list. Partial failures are indicated by
321
- * a `BatchResponse` return value.
440
+ * An error from this method indicates a total failure, meaning that the message
441
+ * was not sent to any of the tokens in the list. Partial failures are indicated
442
+ * by a `BatchResponse` return value.
322
443
*
323
444
* @param message - A multicast message
324
445
* containing up to 500 tokens.
325
446
* @param dryRun - Whether to send the message in the dry-run
326
447
* (validation only) mode.
327
448
* @returns A Promise fulfilled with an object representing the result of the
328
449
* send operation.
450
+ *
451
+ * @deprecated Use {@link Messaging.sendEachForMulticast} instead.
329
452
*/
330
453
public sendMulticast ( message : MulticastMessage , dryRun ?: boolean ) : Promise < BatchResponse > {
331
454
const copy : MulticastMessage = deepCopy ( message ) ;
0 commit comments