I've just started testing Firebase for website push notifications. The basic code seems to work perfectly well on many Android-based browsers (Chrome, Firefox...) apps but not those installed on iOS such Chrome on my iPad or iPhone. I couldn't find any information related to this issue. Am I missing something?
firebase.initializeApp(config);
const messaging = firebase.messaging();
messaging.requestPermission()
.then(function () {
console.log('Notification permission granted.');
// TODO(developer): Retrieve an Instance ID token for use with FCM.
// ...
})
.catch(function (err) {
console.log('Unable to get permission to notify.', err);
});
Chrome on iOS is built on top of the same basic web view as Safari. Since that underlying component doesn't support Web Push, FCM push notifications cannot be delivered to Chrome on iOS.
For future reference, if you get a blank page on your website on iOS browsers.
just wrap your server worker in an if statement by checking if FCM is supported in that browser firebase.messaging.isSupported()
if (firebase.messaging.isSupported()) {
firebase.initializeApp({
'messagingSenderId': 'your code here'
});
...
}
Related
Im implementing Firebase Cloud Messaging notification for my React Native app. For Android, the notification works great, however, for the ios, I faced an error of unable to get the token, too many server request. Here is my snippet of code for getting FCM token + request user's notification permission
const getFcmToken = async () => {
let fcmToken = await AsyncStorage.getItem("fcmToken");
console.log("fcmToken", fcmToken);
if (!fcmToken) {
try {
fcmToken = await messaging().getToken();
if (fcmToken) {
// user has a device token
await AsyncStorage.setItem("fcmToken", fcmToken);
}
} catch (err) {
console.log("Unable to get messaging token.", err);
}
}
};
export async function requestUserPermission() {
const authStatus = await messaging().requestPermission();
const enabled =
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
if (enabled) {
getFcmToken();
} else {
console.log("not enabled");
}
}
When opening the app, the notification permission work fine, just the get FCM Token failed. Please help me with this issues.
I faced a similar issue where my app successfully retrieved FCM tokens for Android devices, whereas iOS responded with a Too many server requests error.
I solved it by re-downloading the GoogleService-Info.plist file from the Firebase Console for the iOS app.
I am not sure why, but it seemed my API key had been blocked or was invalid. After re-downloading the GoogleService-Info.plist file, the API key was updated and everything started working again.
The steps for adding the GoogleService-Info.plist to your React Native project can be found in the Getting Started part of the React Native Firebase Docs where you set up your iOS credentials.
Hope this helps.
I had this issue after I restricted the Firebase APIs to my iOS app.
To fix it I had to add the Firebase Installations API as this one uses the FID (Firebase installation ID) to target devices for message deliveries.
The Firebase installations service (FIS) provides a Firebase installation ID (FID) for each installed instance of a Firebase app.
And
Firebase Cloud Messaging uses Firebase installation IDs to target devices for message delivery.
All the APIs I had enabled were as follow:
FCM Registration API
Firebase App Distribution API
Firebase Cloud Messaging API
Firebase Installations API
Firebase Remote Config API
Mobile Crash Reporting API
Source:
https://firebase.google.com/docs/projects/manage-installations
I use Expo push Notifications to send Notifications to GSM using push token.
My code is :
registerForPush = async () => {
if (Constants.isDevice) {
const { status: existingStatus } = await Permissions.getAsync(
Permissions.NOTIFICATIONS,
);
let finalStatus = existingStatus;
if (existingStatus !== 'granted') {
const { status } = await Permissions.askAsync(
Permissions.NOTIFICATIONS,
);
finalStatus = status;
}
if (finalStatus !== 'granted') {
alert('Failed to get push token for push notification!');
return;
}
const gsm = await Notifications.getExpoPushTokenAsync();
this._storeData('TOKEN_GSM', gsm);
} else {
alert('Must use physical device for Push Notifications');
}
};
async componentDidMount() {
this.registerForPush();
}
When i use Expo to run the App i granted manually the permissions to get the token, but now i ejected to app to run IOS project with Xcode.
I got an error that i can't get push token :
Failed to get push token for push notification
Expo Ejected Apps need to use react-native libraries for notifications.
I recommend: https://github.com/zo0r/react-native-push-notification
There are currently, expo-kit solutions. But those will be depreciated soon in favor of the bare workflow. https://blog.expo.io/expo-sdk-34-is-now-available-4f7825239319
Deprecating ExpoKit in favor of the bare workflow.
We’re continuing to invest in building tooling and documentation around the bare workflow. We believe that this workflow is strictly better than ExpoKit and has lots of advantages for developers, such as full compatibility with libraries in the React Native ecosystem, easier upgrades, and more modular native code that doesn’t include all of the libraries in the Expo monolith. The bare workflow is the easiest and quickest way to achieve optional modules — that is, including native code for only the Expo modules you actually use.
The function getExpoPushTokenAsync() is for Expo app.
If you eject your app, she will no longer depends on Expo and will no longer have access to expo specific function.
you may read :
https://forums.expo.io/t/expokit-push-notifications-on-ejected-app-lots-of-misinformation-even-in-expo-docs-need-clarity/14670
an easy way to make push notification on react-native is to use firebase cloud messaging.
I'm working with Ionic3 and using FirebaseX Cordova Plugin (because firebase plugin it's not working at all) and when the App is foreground (opened) the message get in the App (not as a notification) perfect, but when in background (using another app) the notification don't show... when I open back the App, the message get in the App (not as a notification)...
I'm using the Author example EXACTLY (only changed the bundle id so I could register as a Firebase Project)
I use a paid developer account, I have defined a APN, uploaded to firebase etc.
Activate the Remote Notification in Capabilities (both on Push and Background)
But still...
Something strange is that when the App opens, it says in the log:
2019-10-25 11:20:50.152424-0300 FirebaseX Ionic 3 Example[560:180512] FCM direct channel = true
and when the App goes background, the login says:
2019-10-25 11:20:50.152424-0300 FirebaseX Ionic 3 Example[560:180512] FCM direct channel = false
And when I open the App again it goes back to true again, and receive the notification!
I know that FCM is Firebase Cloud Messagin, so... but I don't know why it turns false
Please, help! Thanks!
I found the solution! Maybe it helps someone... Now with the FirebaseX Cordova Plugin You need to ask for permission explicitly (with the old firebase cordova plugin, was automaticly asked...)
insert this code:
this.firebasePlugin.grantPermission(function(hasPermission){
console.log("Permission was " + (hasPermission ? "granted" : "denied"));
});
and that's it (if the user say 'yes'!)
In firebasex cordova plugin you have to ask for permission like this.
You can only call grantPermission() if hasPermission() returns false:
window.FirebasePlugin.hasPermission(function(hasPermission){
if(!hasPermission){
window.FirebasePlugin.grantPermission(function(permissionGranted){
if(permissionGranted){
console.log("Permission granted");
}else{
console.warn("Permission denied");
}
});
}else{
console.log("Permission already granted");
}
});
When I tried to use Fb and Twitter authentication with firebase it shows below error. Same error shows both on the iOS device and simulator. Could you tell me how to sort out this issue? I'm using Ionic 3 app.
Note: This is working fine on Android device though.
I have used this article: Ionic Social Login using Firebase
Safari cannot open the page because it could not connect to the server
This is the error:
.ts
async loginWithFacebook(): Promise<string> {
try {
const response = await this.afAuth.auth.signInWithRedirect(new firebase.auth.FacebookAuthProvider());
const result = await this.afAuth.auth.getRedirectResult();
return result.additionalUserInfo.profile.email;
}
catch (err) {
console.log(err);
}
I see this error:
Error: This operation is not supported in the environment this
application is running on. "location.protocol" must be http, https or
chrome-extension and web storage must be enabled.
When I use:
firebase.auth().signInWithPopup(provider)
.then(function(result) {
console.log(result);
})
.catch(function(error) {
console.log('popup', error);
//webSettings.setDomStorageEnabled(true);
firebase.auth().signInWithRedirect(provider)
.then(function(result) {
console.log(result);
})
.catch(function(error) {
console.log('redirect', error);
firebase.auth().signInAnonymously().catch(function(error) {
console.log('anonymous', error);
});
});
});
The first two login attempts via popup and redirect fail. It seems to happen only on iOS Safari.
I see others reporting the issue with Cordova, but I don't see an answer and I'm only using web and firebase. Not Cordova or ionic etc.
The anonymous login works on iOS but that is only a test and not what we want to use to use.
If you want to test it you can use https://meetup-reporter.firebaseapp.com/ from Safari on iOS
An example dump of the error object from the returned Promise is:
{"code": "auth/operation-not-supported-in-this-environment",
"constructor": function (a, b)
{this.code="auth/"+a;this.message=b||Xf[a]||"";}, "F": function ()
{return{code:this.code,message:this.message}}, "line": 44, "message":
"This operation is not supported in the environment this application
is running on. \"location.protocol\" must be http, https or
chrome-extension and web storage must be enabled.", "sourceURL":
"https://meetup-reporter.firebaseapp.com//firebase/4.1.2/firebase-auth.js",
"stack":
"https://meetup-reporter.firebaseapp.com//firebase/4.1.2/firebase-auth.js:44:638\nhttps://meetup-reporter.firebaseapp.com//firebase/4.1.2/firebase-auth.js:45:258\nA#https://meetup-reporter.firebaseapp.com//firebase/4.1.2/firebase-auth.js:44:545\nD#https://meetup-reporter.firebaseapp.com//firebase/4.1.2/firebase-auth.js:45:242\nsignInWithPopup#https://meetup-reporter.firebaseapp.com//firebase/4.1.2/firebase-auth.js:241:48\na#https://meetup-reporter.firebaseapp.com/__/firebase/4.1.2/firebase-auth.js:260:432\nhttps://meetup-reporter.firebaseapp.com/scripts/main.js:430:36",
"toJSON": function () {var
a=Array.prototype.slice.call(arguments);a:{var
e=Array.prototype.slice.call(a);var l=0;for(var
n=!1,C=0;Cl||l>=fk.length)throw new N("internal-error","Argument
validator received an unsupported number of arguments.");e=fk[l]+"
argument "+(e.name?'"'+e.name+'" ':"")+"must be "+e.N+".";break
a}e=null}}if(e)throw new N("argument-error",d+" failed: "+e);return
b.apply(this,a);}}
signInWithRedirect actually works in Cordova now: https://firebase.google.com/docs/auth/web/cordova
signInWithPopup and signInWithRedirect should also work for iOS7 and up. I just tested both on an iOS 7 device and they both work. What you are experiencing is likely to the fact that you are using this operation in Safari Private/Incognito mode where web storage is disabled. These operations depend on web storage in order to securely communicate the OAuth result to the parent page. You will need to ask your users to switch to regular mode when this happens, or you can use the Google Sign-in JS SDk to get the OAuth credential and then signInWithCredential. I think it may work in incognito mode.