问题描述
我正在开发适用于 Android 和 iOS 的 Ionic 5 应用.我正在使用 angularfire https://github.com/angular/angularfire/tree/v5 我遇到了一些问题.特别是,这个库在使用 Firestore 时效果很好,但是当我尝试使用 Cloud Messaging 在我的 Android 设备上接收通知时,它引发了一个错误:FirebaseError: Messaging: This browser does not support the API's required to useFirebase SDK.(消息/不受支持的浏览器).我按照此处链接的 GitHub 存储库上提供的教程进行操作,并尝试在浏览器上使用它,并且效果很好.我怀疑这个库不能与 Ionic 一起正常工作,因此可以使用某些服务,例如 Firestore,而其他服务则不能.任何人都有一些想法来解决这个问题?下面是我的服务的代码片段:
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)},
);
}
}
谢谢!
推荐答案
经过大量研究,我终于找到了解决方案.我把它贴在这里,以便将来可以解决类似的问题.这里https://caniuse.com/#feat=push-api,如道格·史蒂文森建议,列出了支持的浏览器.这里 https://developer.chrome.com/multidevice/webview/overview,在常见问题之一,他们指出 Android WebView 基于 Chrome for Android 版本 30.0.0,不受支持.因此,我不得不使用名为 FirebaseX 的 Cordova 插件:
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
还需要另外两个插件:
ionic cordova plugin add cordova-plugin-androidx
ionic cordova plugin add cordova-plugin-androidx-adapter
并且您的应用在 Firebase 控制台中同时注册为 Android 和 iOS,这为您提供了两个文件以包含在您项目的根文件夹中:google-services.json和 GoogleService-Info.plist.添加此类插件后,运行以下命令(可能不需要,但建议使用):
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.jsonand 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
在最后一个命令中,我遇到了另一个问题:任务 ':app:transformDexArchiveWithExternalLibsDexMergerForDebug' 的执行失败.我按照本指南解决了这个问题:https://developer.android.com/studio/build/multidex#mdex-gradle.(我刚刚添加了 multiDexEnabled true
,也许有一种方法可以默认包含它,顺便说一下).它现在可以工作了,尽管我必须以下列方式调整我的代码才能使用 FirebaseX 来执行 requestToken 操作:
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)},
);
}
}
谢谢 Doug,不知何故你帮助我度过了难关!
Thank you Doug, somehow you helped me get through it!
这篇关于FirebaseError: Messaging: 此浏览器不支持使用 Firebase SDK 所需的 API.(消息/不受支持的浏览器)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!