@@ -170,8 +170,13 @@ export class NotificationService {
170170
171171 console . log ( `[NOTIF] Sending push to ${ allTokens . length } token(s) for eName: ${ eName } ` ) ;
172172
173- const pushResults = await Promise . allSettled (
174- allTokens . map ( async ( { token, platform } ) => {
173+ // Cycle through tokens sequentially: try each one, remove bad tokens
174+ // inline, and keep going until at least one succeeds.
175+ const badTokens : string [ ] = [ ] ;
176+ let delivered = false ;
177+
178+ for ( const { token, platform } of allTokens ) {
179+ try {
175180 const res = await fetch ( `${ triggerUrl } /api/send` , {
176181 method : "POST" ,
177182 headers : { "Content-Type" : "application/json" } ,
@@ -183,31 +188,32 @@ export class NotificationService {
183188 signal : AbortSignal . timeout ( 10000 ) ,
184189 } ) ;
185190 const data = await res . json ( ) ;
186- if ( ! data . success ) {
187- throw new Error ( data . error || "Push send failed" ) ;
191+
192+ if ( data . success ) {
193+ console . log ( `[NOTIF] Push delivered via token ${ token . slice ( 0 , 8 ) } … for ${ eName } ` ) ;
194+ delivered = true ;
195+ // Keep sending to remaining tokens — user may have multiple
196+ // devices (phone + tablet) that should all receive the notif.
197+ continue ;
188198 }
189- return data ;
190- } )
191- ) ;
192199
193- const pushSucceeded = pushResults . filter ( r => r . status === "fulfilled" ) . length ;
194- const pushFailed = pushResults . filter ( r => r . status === "rejected" ) . length ;
200+ // Send returned an explicit failure
201+ const error = data . error || "Push send failed" ;
202+ console . error ( `[NOTIF] Push failed for token ${ token . slice ( 0 , 8 ) } …:` , error ) ;
195203
196- // Collect tokens that returned a known "bad token" error so we can purge them
197- const badTokens : string [ ] = [ ] ;
198- pushResults . forEach ( ( r , i ) => {
199- if ( r . status === "rejected" ) {
200- console . error ( `[NOTIF] Push failed for token index ${ i } :` , r . reason ) ;
201- if ( isBadTokenError ( r . reason ) ) {
202- badTokens . push ( allTokens [ i ] . token ) ;
204+ if ( isBadTokenError ( error ) ) {
205+ badTokens . push ( token ) ;
206+ console . log ( `[NOTIF] Bad token ${ token . slice ( 0 , 8 ) } … queued for removal, trying next…` ) ;
203207 }
204- }
205- } ) ;
208+ } catch ( err ) {
209+ const msg = err instanceof Error ? err . message : String ( err ) ;
210+ console . error ( `[NOTIF] Push error for token ${ token . slice ( 0 , 8 ) } …:` , msg ) ;
206211
207- if ( pushFailed > 0 ) {
208- console . log ( `[NOTIF] Push results for ${ eName } : ${ pushSucceeded } sent, ${ pushFailed } failed` ) ;
209- } else {
210- console . log ( `[NOTIF] Push sent successfully to ${ pushSucceeded } token(s) for ${ eName } ` ) ;
212+ if ( isBadTokenError ( err ) ) {
213+ badTokens . push ( token ) ;
214+ console . log ( `[NOTIF] Bad token ${ token . slice ( 0 , 8 ) } … queued for removal, trying next…` ) ;
215+ }
216+ }
211217 }
212218
213219 // Purge bad tokens from both Verification and DeviceToken tables
@@ -216,7 +222,13 @@ export class NotificationService {
216222 await this . removeBadTokens ( eName , badTokens ) ;
217223 }
218224
219- return pushSucceeded > 0 || pushFailed === 0 ;
225+ if ( delivered ) {
226+ console . log ( `[NOTIF] Push delivered for ${ eName } ` ) ;
227+ } else {
228+ console . log ( `[NOTIF] Push failed for all ${ allTokens . length } token(s) for ${ eName } ` ) ;
229+ }
230+
231+ return delivered ;
220232 }
221233
222234 private async removeBadTokens ( eName : string , badTokens : string [ ] ) : Promise < void > {
0 commit comments