@@ -170,14 +170,20 @@ export interface ApnsPayload {
170
170
export interface Aps {
171
171
alert ?: string | ApsAlert ;
172
172
badge ?: number ;
173
- sound ?: string ;
173
+ sound ?: string | CriticalSound ;
174
174
contentAvailable ?: boolean ;
175
175
category ?: string ;
176
176
threadId ?: string ;
177
177
mutableContent ?: boolean ;
178
178
[ customData : string ] : any ;
179
179
}
180
180
181
+ export interface CriticalSound {
182
+ critical ?: boolean ;
183
+ name ?: string ;
184
+ volume ?: number ;
185
+ }
186
+
181
187
export interface ApsAlert {
182
188
title ?: string ;
183
189
subtitle ?: string ;
@@ -299,6 +305,7 @@ function validateAps(aps: Aps) {
299
305
MessagingClientErrorCode . INVALID_PAYLOAD , 'apns.payload.aps must be a non-null object' ) ;
300
306
}
301
307
validateApsAlert ( aps . alert ) ;
308
+ validateApsSound ( aps . sound ) ;
302
309
303
310
const propertyMappings : { [ key : string ] : string } = {
304
311
contentAvailable : 'content-available' ,
@@ -332,6 +339,40 @@ function validateAps(aps: Aps) {
332
339
}
333
340
}
334
341
342
+ function validateApsSound ( sound : string | CriticalSound ) {
343
+ if ( typeof sound === 'undefined' || validator . isString ( sound ) ) {
344
+ return ;
345
+ } else if ( ! validator . isNonNullObject ( sound ) ) {
346
+ throw new FirebaseMessagingError (
347
+ MessagingClientErrorCode . INVALID_PAYLOAD ,
348
+ 'apns.payload.aps.sound must be a string or a non-null object' ) ;
349
+ }
350
+
351
+ const volume = sound . volume ;
352
+ if ( typeof volume !== 'undefined' ) {
353
+ if ( ! validator . isNumber ( volume ) ) {
354
+ throw new FirebaseMessagingError (
355
+ MessagingClientErrorCode . INVALID_PAYLOAD ,
356
+ 'apns.payload.aps.sound.volume must be a number' ) ;
357
+ }
358
+ if ( volume < 0 || volume > 1 ) {
359
+ throw new FirebaseMessagingError (
360
+ MessagingClientErrorCode . INVALID_PAYLOAD ,
361
+ 'apns.payload.aps.sound.volume must be in the interval [0, 1]' ) ;
362
+ }
363
+ }
364
+ const soundObject = sound as { [ key : string ] : any } ;
365
+ const key = 'critical' ;
366
+ const critical = soundObject [ key ] ;
367
+ if ( typeof critical !== 'undefined' && critical !== 1 ) {
368
+ if ( critical === true ) {
369
+ soundObject [ key ] = 1 ;
370
+ } else {
371
+ delete soundObject [ key ] ;
372
+ }
373
+ }
374
+ }
375
+
335
376
/**
336
377
* Checks if the given alert object is valid. Alert could be a string or a complex object.
337
378
* If specified as an object, it must have valid localization parameters. If successful, transforms
0 commit comments