angular - 如何在应用程序位于前台时显示弹出通知

标签 angular firebase firebase-cloud-messaging progressive-web-apps

我正在构建一个 Angular PWA,其中集成了 Firebase 推送通知。我已经完成了所有操作,我仅在应用程序的后台收到弹出通知通知,但我希望当用户使用该应用程序时弹出通知应该出现,或者您可以说,当应用程序位于前台。

组件.ts:

import {Component, OnInit} from '@angular/core';
import * as firebase from 'firebase';
import {AngularFireDatabase, AngularFireList} from 'angularfire2/database';
//import {AngularFireDatabase, FirebaseListObservable, FirebaseObjectObservable} from 'angularfire2/database-deprecated';
import {PushService} from './push.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})


export class AppComponent {


  // Declare the variables used
  messaging: any
  token: any  // Stores the current token ID instance generated
  items: AngularFireList<any[]>
  itemsDisplay: AngularFireList<any[]> // List observable for template view (Optional. items itself can be used)
  itemsArr: any[] // Stores the token IDs retrieved from the firebase database 
  hideToken: boolean = false

  // Notificayion object
  pushData: any = {
    'notification': {
      "title": "Background Message Title",
      "body": "Background Message Body"
    },
    "to": ""
  }

  constructor(public db: AngularFireDatabase, private pushService: PushService) {

    // Creates a Firebase List Observable and calls the data in it
    this.itemsDisplay = db.list('/items')

    // Declaring the property value of messaging
    this.messaging = firebase.messaging();

    // Check for token refresh
    this.messaging.onTokenRefresh(function() {
      this.messaging.getToken()
        .then(function(refreshedToken) {
          console.log('Token refreshed.');
        })
        .catch(function(err) {
          console.log('Unable to retrieve refreshed token ', err);
        });
    });
    // Obtaining the firebase data and retrieving token ID values separately
    this.itemsArr = []  // Reinitialize the array to prevent data duplication
    this.items = this.db.list('/items');
    this.items.valueChanges().subscribe(snapshots => {

      console.log("SNAPSHOT RECIEVED-----"+snapshots);
      //snapshots.forEach(snapshot => {
      //  console.log("Hey ,, snapshot......"+snapshot);
     // this.itemsArr.push(snapshot.child("items").val().tokenID);
      // });
    });
    // console.log(this.itemsArr)
  }

  // Check for duplicates in token subscription
  checkToken(token, arr) {
    console.log("Inside check token function")
    console.log(arr)
    console.log(token)
    let counter: number = 0
    for (var i = 0; i < arr.length; i++) {
      if (arr[i] === token) {
        counter++
      }
    }
    console.log("Counter value", counter)
    return counter
  }

  // Generate Push through an event
  generatePush() {
    console.log("Inside push function")
    console.log(this.pushData.to)
    if (this.pushData.to === "") {
      console.log("No token available")
      return
    }
    this.pushService.generatePush(this.pushData)
      .subscribe(data => {console.log("Succesfully Posted")}, err => console.log(err))
  }

  // Function to get the data from Firebase Database
  getDataFromFb() {
    this.hideToken = true
  }

  ngOnInit() {
    // Prompt user to grant permission for notifications on loading components
    const self = this
    this.items = this.db.list('/items')
    this.messaging.requestPermission()
      .then(function() {
        console.log('Notification permission granted.');
        return self.messaging.getToken()
          .then(function(currentToken) {
            if (currentToken) {
              self.token = currentToken
              self.pushData.to = self.token
              console.log(self.pushData.to)

              // Set a timeout so as to enable all the data to be loaded
              setTimeout(() => {
                if (self.checkToken(self.token, self.itemsArr) === 0) {
                  console.log("Push occurrence")
                  //self.items.push({tokenID: currentToken})
                } else {
                  console.log("User is already subscribed")
                }
              }, 6500)
              // Displays the current token data
              console.log("currentToken: ", currentToken);
              console.log("Stored token: ", self.token);
            } else {
              // Show permission request.
              console.log('No Instance ID token available. Request permission to generate one.');
            }
          })
          .catch(function(err) {
            console.log('An error occurred while retrieving token.', err);
          });
      })
      .catch(function(err) {
        console.log('Unable to get permission to notify. ', err);
      })

    // Handle incoming messages. Called when:
    // - a message is received while the app has focus
    // - the user clicks on an app notification created by a sevice worker `messaging.setBackgroundMessageHandler` handler.
    this.messaging.onMessage(function(payload) {
      console.log("Message received. ", payload);
    });
  }

}

以下是在后台显示通知的代码:

messaging.setBackgroundMessageHandler(function(payload) {
        console.log('[firebase-messaging-sw.js] Received background message ', payload);
        // Customize notification here
        const notificationTitle = 'Background Message Title';
        const notificationOptions = {
            body : 'Background Message body.',
            icon : '/firebase-logo.png'
        };

        return self.registration.showNotification(notificationTitle,
            notificationOptions);
    });

请告诉我,我该如何实现该功能。

最佳答案

这样的事情应该有帮助:

import { Inject, Injectable } from '@angular/core';
import { FirebaseApp } from "angularfire2";
import * as firebase from 'firebase/app';
import 'firebase/messaging';

@Injectable()
export class MessagingService {
  private messaging: firebase.messaging.Messaging;

  constructor(
    @Inject(FirebaseApp) private _firebaseApp: firebase.app.App
  ) {
    this.messaging = firebase.messaging(this._firebaseApp);
  }

  receiveMessage() {
    this.messaging.onMessage((payload) => {
      //do stuff
    });
  }
}

在您的组件(可能是 AppComponent)中调用 receiveMessage()

还将以下内容添加到您的 AppModule 中:

import { AngularFireModule } from '@angular/fire';
.....
AngularFireModule.initializeApp({/*firebase settings*/})

关于angular - 如何在应用程序位于前台时显示弹出通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50902692/

相关文章:

带有 TensorFlow 的 Angular2

Angular/Firebase 身份验证 - 使 bool 值从服务到组件可观察?

android - FCM 通知 "click_action"不工作

jquery - 火力地堡错误 : Messaging: We are unable to register the default service worker

angular - 组件是2个模块声明的一部分

angular - angular i18n 应用程序的 Nginx 配置

android - 如何在两个不同的项目中使用 firebase?

android - 如何解决有关导出的 Firebase 消息服务实现的 android lint 投诉?

angular - RxJS 和 angular.io : an Observable<Array<T>> where T contains an observable array

angular - Angular2 中处理错误的最佳实践