Search code examples
javascriptangularpush-notificationreloadionic4

Update view on a page after an fcm push notification has been received and I'm on the same page


I've an app in Ionic4 which is receiving FCM push notifications for various data updates. Push is working without issues, in the data payload of the notification I put various tags that I then use in the app to change the behaviour according to the payload, for example change the title and description of an Alert Controller that I use to manage foreground notifications:

this.FCM.onNotification()
.subscribe( data => {
   if (data.wasTapped) {
     this.router.navigateByUrl(data.mobile_page);
} else {
 this.presentAlertConfirm(data);
//this.router.navigateByUrl(data.mobile_page);
}
});   

[...]

async presentAlertConfirm(data) {

var dataheader;

// Verifico il tipo di messaggio nel payload della notifica push 

if (data.msgtype == 'msg') {
  dataheader = 'Nuovo Messaggio';
}

[...]

var messageurl = data.mobile_page;

const alert = await this.alertController.create({
  header: dataheader,
  message: 'Premere OK per visualizzare',
  buttons: [
    {
      text: 'Ignora',
      role: 'cancel',
      cssClass: 'secondary',
      handler: (blah) => {
        console.log('Confirm Cancel: blah');
      }
    }, {
      text: 'OK',
      handler: () => {
        this.router.navigateByUrl(data.mobile_page);
        console.log('Confirm Okay');
      }
    }
  ]
});

So far, this part is working without problem. If I'm in the app and receive, for example, a new message, the Alert popup will appear and I'm able, clicking "OK" to get routed to the page where the message is shown. Here comes the tricky part which I was not able to solve by myself. If I receive another message while I'm in the message page, I get the Alert popup, but even if I click "OK", the view is not rendered again and the new message is not shown. I added, as a workaround, a refresh button and a ion-refresher in the page that do the work, but I'd like to know if it's even possible to achieve what I'm looking for, to have the new message displayed without having to manually click the refresh button or swipe down to activate the ion-refresher.

This is the code I have in ngOnInit() on the message detail page:

this.badge.clear();
this.getLoggedUserId();
this.getMessageSingleThread(this.route.snapshot.paramMap.get('thread_id'));

The getMessageSingleThread function invokes a rest method on my web service, and it's the method that should be called after clicking OK on the notification popup.

I tried a bunch of different solutions found here and in other sites, including NgZone, without luck. I'm sure I'm doing something stupid. So far, all the examples where using a single page with both the FCM subscription and the reload, Which I'm sure is a working solution, but not applicable to my case since I have a multipage app anche the FCM is coded in app.component.ts.

Thanks a lot


Solution

  • As mentioned in the comments, a possible solution (probably not the greatest, but still worth the implementation) is to use a Subject on a shared singleton service in order to be able to notify any view which is currently subscribed to that subject that a new message has been received.

    The service part involves declaring a Subject and providing a method to emit values from it.

    import { Injectable } from '@angular/core'; import { Subject } from 'rxjs';

    @Injectable({
      providedIn: 'root'
    })
    export class SharedService {
      /**
       * Holds the shared reference of the subject.
       */
      public _OnMessageReceivedSubject: Subject<string>;
    
      public constructor() {
        // Creates a new subject.
        this._OnMessageReceivedSubject = new Subject<string>();
      }
    
     /**
     * emits a message. 
     */
      public emitMessageReceived(msg: string): void {
        this._OnMessageReceivedSubject.next(msg);
      }
    }
    

    Stackblitz to play with