I have added the script and One Signal SDKs to my Angular 6 app. I am able to receive push notifications in the app on Chrome (Windows). How to capture the additional data fields that are sent in the one signal push notification?
This is the script that I have added in the index.html file.
<script>
var OneSignal = window.OneSignal || [];
OneSignal.push(function() {
OneSignal.init({
appId: "xxxx-xxxx-xxxx-xxxx",
});
});
</script>
Try this, in the event you will find the additional data fields
var OneSignal = window['OneSignal'] || [];
OneSignal.push(function() {
//This event can be listened to via the on() or once() listener
OneSignal.on('notificationDisplay', function(event) {
console.warn('OneSignal notification displayed,data:', event);
});
});
Related
We have a react-native app that runs its notifications through FCM with the following environment:
react-native: 0.59.10,
react-native-firebase: 5.5.6
All the configs have been set up, certificates provisioned, etc. Until the very present time, notifications have been working like a clock, but recently we stopped receiving notifications in the foreground.
Here's the NotificationsManager code:
import firebase from 'react-native-firebase';
const CHANNEL = 'default';
...
const localNotificationListener = React.useRef();
const notificationOpenListener = React.useRef();
const onTokenRefreshListener = React.useRef();
const receiveForegroundPN = (n) => {
const notification = new firebase.notifications.Notification()
.setNotificationId(n.notificationId)
.setTitle(n.title)
.setSubtitle(n.subtitle)
.setBody(n.body)
.setData(n.data);
if (Platform.OS === 'android') {
notification
.android.setChannelId(CHANNEL)
.android.setSmallIcon('ic_launcher');
}
firebase.notifications().displayNotification(notification);
};
React.useEffect(() => {
const channel = new firebase.notifications.Android.Channel(
CHANNEL,
'Bank Notifications',
firebase.notifications.Android.Importance.Max,
).setDescription('*****');
firebase.notifications().android.createChannel(channel);
localNotificationListener.current = firebase.notifications().onNotification(receiveForegroundPN);
notificationOpenListener.current = firebase.notifications().onNotificationOpened(openNotification);
onTokenRefreshListener.current = firebase.messaging().onTokenRefresh((fcmToken) => {
registerToken({
device_token: fcmToken,
});
});
runFlow();
return () => {
localNotificationListener.current();
notificationOpenListener.current();
onTokenRefreshListener.current();
};
}, []);
Notifications work just fine on both platforms while the app is in the background, but never show when the app is in the foreground.
I've tried setting show_on_foreground: "true", but that didn't help. Actually, I tried logging anything in the receiveForegroundPN method but it was never called, i.e. it looks like notifications are never received from firebase when app is running.
What might be the issue here and possible solutions to make notifications work?
Update
All of a sudden, within the hour of posting this, iOS started to receive foreground notifications. Android still doesn't work, yet it used to.
I am having a similar issue as well.. ,
The onNotification method doesn't get trigerred so i tried the onMessage method instead which seems to work for foreground.
firebase.messages().onMessage(msg => {
// ... your code here
});
Iterating on Amr's answer.
As per documentation, you must hook into firebase's callbacks to get notified when a push notification is received in foreground.
From that point you can decide how to handle the message.
The simplest way is to display an alert Alert.alert('A new FCM message arrived!', JSON.stringify(remoteMessage)); or
You can use another library to display a local notification. Here is an example using react-native-notifications library:
// Just call the hook in some root component that's always present
export const useDisplayRemoteNotifications: () => void = () => {
useEffect(() => {
return messaging().onMessage(async remoteMessage => {
Notifications.postLocalNotification({
title: remoteMessage.notification?.title || '',
body: remoteMessage.notification?.body || '',
fireDate: dayjs().add(1, 'second').toDate(), // one second later
});
});
}, []);
};
I'm working on a Firebase Cloud Function, to send triggered push notifications.
Right now my function sends a push as soon as an user triggers the "IAP" event in my app.
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendIAPAnalytics = functions.analytics.event('IAP').onLog((event) => {
const user = event.user;
const uid = user.userId; // The user ID set via the setUserId API.
sendPushToUser();
return true;
});
function sendPushToUser(uid) {
// Fetching all the user's device tokens.
var ref = admin.database().ref(`/users/${uid}/tokens`);
return ref.once("value", function(snapshot){
const payload = {
notification: {
title: 'Hello',
body: 'Open the push'
}
};
console.log("sendPushToUser ready");
admin.messaging().sendToDevice(snapshot.val(), payload)
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
}
This functions works, push are sent and received.
I read some news about scheduling for Firebase Cloud Functions:
https://medium.com/#pascalluther/scheduling-firebase-cloud-functions-with-cloud-scheduler-b5ec22ace683
https://firebase.googleblog.com/2019/04/schedule-cloud-functions-firebase-cron.html
I understood, it's only for HTTP triggers ou PUB/SUB triggers.
So for now it's always impossible to trigger functions with delays, by writing in realtime database or when analytics events are triggered.
Am I right? or is there a trick?
I read nothing about this.
EDIT: Official documentation
https://firebase.google.com/docs/functions/schedule-functions
My syntax is wrong but I need something like this:
function sendPushToUser(uid) {
var ref = admin.database().ref(`/users/${uid}/tokens`);
return ref.once("value", function(snapshot){
const payload = {
notification: {
title: 'Hello',
body: 'Open the push'
}
};
functions.pubsub.schedule('at now + 10 mins').onRun((context) => {
admin.messaging().sendToDevice(snapshot.val(), payload)
})
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
}
There is no built-in way to retrigger Cloud Functions with a delay. If you want such functionality you will have to build that yourself, for example by scheduling a function to run periodically and then see what tasks need to be triggered. See my answer here: Delay Google Cloud Function
As Doug commented, you can use Cloud Tasks to schedule individual invocations. You'd dynamically create the task, and then have it call a HTTP function.
Here is a snippet of code from a chat app developed with Firebase and react native.
on = callback =>
this.ref
.limitToLast(20)
.on('child_added', snapshot => callback(this.parse(snapshot)));
}
Here whenever there is a new message is posted to Firebase, the callback in the app will sync with the firebase db and retrieve last 20 message.
I understand how push notification works and know in-app message is not push notification. But I didn't see a good technical article explaining how in app chat messages are synced between front end app and the backend database. I would think periodical pulling of backend database server from app would not be the most efficient way.
Here are more Firebase code associated with the code above:
import firebase from 'firebase'; // 4.8.1
class Fire {
constructor() {
this.init();
this.observeAuth();
}
init = () =>
firebase.initializeApp({
....
});
observeAuth = () =>
firebase.auth().onAuthStateChanged(this.onAuthStateChanged);
onAuthStateChanged = user => {
...
};
get uid() {
...
}
get ref() {
return firebase.database().ref('messages');
}
parse = snapshot => {
...
return message;
};
on = callback =>
this.ref
.limitToLast(20)
.on('child_added', snapshot => callback(this.parse(snapshot)));
}
When you attach the first listener from the client to the database, the client opens a web socket connection to the server. It then sends the query/reference details to the server, which in turn loads the initial data (and send it back) and registers an internal listener on the server for changes.
From that moment on, if any change is made to the relevant data, the server scans the list of registrations, and sends updates to the affected clients. Those clients in turn raise the correct events, such as child_added and child_removed.
I need my onPublish method (firebase side) to get only one message at time.
My code is like this:
Google Cloud (AppEngine):
const pubsub = new PubSub({
projectId: config.project,
});
const topicName = 'projects/'+config.project+'/topics/user_assigner';
const dataBuffer = Buffer.from(dataToSend);
pubsub
.topic(topicName)
.publisher()
.publish(dataBuffer, (err, messageId)=> {
console.log("call back")
console.log("err",err)
console.log("messageId",messageId)
resolve(messageId)
})
Firebase
var functions = require('firebase-functions');
module.exports =
functions.pubsub.topic('user_assigner').onPublish((event) => {
return someAsyncCode() //return promise;
});
I need the code someAsyncCode to run messages one by one, is there a way to do that?
I have seen on the documentation of the publisher the batch maxMessages but I think that is to set the limit when the publisher push new messages to the queue of messages. So, if I set that attibute to one is the same, the publisher will push one buy one(gcloud side), and the onPublish (firebase side) will get all the messages no matter if it is processing one.
How to set the firebase.auth.RecaptchaVerifier in react native using firebase web method to verify phone number and authenticate by receiving OTP on device.Tried with some Methods but not working on mobile.
Code for react native using Web Method:
var appVerifier = firebase.auth.RecaptchaVerifier;
// window.recaptchaVerifier =
// new firebase.auth.RecaptchaVerifier('recaptcha-container');
firebase.auth().signInWithPhoneNumber('+919843191338', appVerifier)
.then(function (confirmationResult) {
Alert.alert(confirmationResult);
window.confirmationResult = confirmationResult;
}).catch(function (error) {
// Error; SMS not sent
// ...
});
You can enable auto verification by enabling SafetyNet API
Check this for detailed information:
https://firebase.google.com/docs/auth/android/phone-auth