FirebaseError: Messaging: This browser doesn't support the API's required to use the firebase SDK. (messaging/unsupported-browser)

时光毁灭记忆、已成空白 提交于 2021-02-05 08:45:17

问题


I'm developing a Ionic 5 app both for Android and iOS. I'm using angularfire https://github.com/angular/angularfire/tree/v5 and I'm having some issues. In particular, this library works good when using Firestore, but when I try to use Cloud Messaging to receive notifications on my Android device, it raises an error: FirebaseError: Messaging: This browser doesn't support the API's required to use the firebase SDK. (messaging/unsupported-browser). I followed the tutorial available on the GitHub repository linked here and I tried to use it on browser and it works fine. My suspect is that this library doesn't work properly with Ionic, so some services, like Firestore, can be used and others not. Anyone has some ideas to solve this issue? Here follows the snippet of code of my service:

import { Injectable } from '@angular/core';
import { AngularFireMessaging } from '@angular/fire/messaging';
import { AngularFireFunctions } from '@angular/fire/functions';
import { ToastController } from '@ionic/angular';

/* //Fixing temporary bug in AngularFire - Found on Internet
import * as app from 'firebase';
const _messaging = app.messaging();
_messaging.onTokenRefresh = _messaging.onTokenRefresh.bind(_messaging);
_messaging.onMessage = _messaging.onMessage.bind(_messaging); */

@Injectable({
  providedIn: 'root'
})
export class FcmService {
  token: any; 

  constructor(private toastController: ToastController, private afm: AngularFireMessaging, private aff: AngularFireFunctions) { }

  async makeToast(message: string){
    const toast = await this.toastController.create({
      duration: 5000,
      message: message,
      position: 'top',
      buttons: [
        {
          side: 'end',
          text: 'Close',
          role: 'cancel',
          handler: () => {
            console.log('Favorite clicked');
          }
        }]
    });
    toast.present();
  }

  getPermission(){
    this.afm.requestToken
      .subscribe(
        (token) => { console.log('Permission granted! Save to the server!', token); this.token = token;},
        (error) => { console.error(error); },  
      );
  }

  showMessages(){
    return this.afm.messages
      .subscribe(
        (message) => {console.log(message);}
      );
  }

  subscribe(topic: string){
    this.aff.httpsCallable('subscribeToTopic')({topic: topic, token: this.token})
      .subscribe(
        (_) => {this.makeToast("Notifications about "+topic+" activated.")},
        (error) => {console.log(error)},
      );
  }

  unsubscribe(topic: string){
    this.aff.httpsCallable('unsubscribeFromTopic')({topic: topic, token: this.token})
      .subscribe(
        (_) => {this.makeToast("Notifications about "+topic+" deactivated.")},
        (error) => {console.log(error)},
      );
  }
}

Thank you!


回答1:


After a lot of reasearch I finally found a solution. I'm posting it here, so that future similar issues can be solved. Here https://caniuse.com/#feat=push-api, as Doug Stevenson suggested, the supported browsers are listed. Here https://developer.chrome.com/multidevice/webview/overview, in one of the FAQs, they state that Android WebView is based on Chrome for Android version 30.0.0 which is not supported. Hence, I had to use a Cordova plugin called FirebaseX:

ionic cordova plugin add cordova-plugin-firebasex
npm install @ionic-native/firebase-x

which also requires this other two plugins:

ionic cordova plugin add cordova-plugin-androidx
ionic cordova plugin add cordova-plugin-androidx-adapter

and that your app is registred both as Android and iOS in the Firebase console, which gives you two files to be included in the root folder of your project: google-services.json and GoogleService-Info.plist. Once you have added such plugins, run the following commands (they could not be needed, but it is recommended):

cordova clean
ionic cordova build android

On the last command, I had another issue: Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'. I solved it by following this guide: https://developer.android.com/studio/build/multidex#mdex-gradle. (I just added the multiDexEnabled true, maybe there is a way to include it by default, as it should be by the way). It is now working, although I had to adapt my code in the following way to use FirebaseX to perform the requestToken operation:

import { Injectable } from '@angular/core';
import { AngularFireMessaging } from '@angular/fire/messaging';
import { AngularFireFunctions } from '@angular/fire/functions';
import { ToastController, Platform } from '@ionic/angular';
import { FirebaseX } from "@ionic-native/firebase-x/ngx";

/* //Fixing temporary bug in AngularFire - Found on Internet
import * as app from 'firebase';
const _messaging = app.messaging();
_messaging.onTokenRefresh = _messaging.onTokenRefresh.bind(_messaging);
_messaging.onMessage = _messaging.onMessage.bind(_messaging); */

@Injectable({
  providedIn: 'root'
})
export class FcmService {
  token: any; 

  constructor(private toastController: ToastController, private afm: AngularFireMessaging, private aff: AngularFireFunctions, private platform: Platform,
    private firebase: FirebaseX) { }

  async makeToast(message: string){
    const toast = await this.toastController.create({
      duration: 5000,
      message: message,
      position: 'top',
      buttons: [
        {
          side: 'end',
          text: 'Close',
          role: 'cancel',
          handler: () => {
            console.log('Favorite clicked');
          }
        }]
    });
    toast.present();
  }

  async getPermission(){
    if (this.platform.is("android")){
      this.firebase.getToken().then(
        (token) => console.log(token)
      );
    } else {
      await this.afm.requestToken
      .subscribe(
        (token) => { console.log('Permission granted! Save to the server!', token); this.token = token;},
        (error) => { console.error(error); },  
      );
    }
  }

  showMessages(){
    return this.afm.messages
      .subscribe(
        (message) => {console.log(message);}
      );
  }

  subscribe(topic: string){
    this.aff.httpsCallable('subscribeToTopic')({topic: topic, token: this.token})
      .subscribe(
        (_) => {this.makeToast("Notification about "+topic+" activated.")},
        (error) => {console.log(error)},
      );
  }

  unsubscribe(topic: string){
    this.aff.httpsCallable('unsubscribeFromTopic')({topic: topic, token: this.token})
      .subscribe(
        (_) => {this.makeToast("Notification about "+topic+" deactivated.")},
        (error) => {console.log(error)},
      );
  }
}

Thank you Doug, somehow you helped me get through it!




回答2:


On the main documentation page, it states:

The FCM JavaScript API lets you receive notification messages in web apps running in browsers that support the Push API. This includes the browser versions listed in this support matrix and Chrome extensions via the Push API.

If you navigate to that link for the support matrix, you will find out if your browser supports the push API. If you try to use FCM on an unsupported browser, you will get that message. You will need to figure out if the host OS supports this API.



来源:https://stackoverflow.com/questions/60945213/firebaseerror-messaging-this-browser-doesnt-support-the-apis-required-to-use

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!