I m coding an application who need push notification in background(app was killed).
its notification app for twitch.
I m store channels with redux persist(asyncstorage).
What should i do? do u have any documentation directly about that ?
You can use a push notification library like https://github.com/zo0r/react-native-push-notification and a background task library like https://github.com/transistorsoft/react-native-background-fetch. Then you can call your push notification(s) inside background tasks.
Keep in mind that the minimum interval between background tasks being run is 15 minutes. So the interval can only be 15 minutes or longer.
To make this answer more useful, here is a previous implementation I've used to handle push notifications in the background to give you an idea of how to go about it:
import PushNotification from 'react-native-push-notification';
export default class NotificationService {
constructor(onRegister, onNotification) {
this.configure(onRegister, onNotification);
this.lastId = 0;
}
// Handles a user push notification registration
configure(onRegister, onNotification, gcm = '') {
PushNotification.configure({
// (optional) Called when Token is generated (iOS and Android)
onRegister: onRegister,
// (required) Called when a remote or local notification is opened or received
onNotification: onNotification,
// ANDROID ONLY: GCM Sender ID (optional - not required for local notifications, but is need to receive remote push notifications)
senderID: gcm,
/**
* (optional) default: true
* - Specified if permissions (ios) and token (android and ios) will requested or not,
* - if not, you must call PushNotificationsHandler.requestPermissions() later
*/
requestPermissions: true,
});
}
// Send a direct push notification to the user
localNotif() {
this.lastId++;
PushNotification.localNotification({
/* Android Only Properties */
id: '' + this.lastId,
bigText: 'My big text that will be shown when notification is expanded',
subText: 'This is a subText',
/* iOS and Android properties */
title: 'Local Notification',
message: 'My Notification Message',
actions: '["Yes", "No"]', // (Android only) See the doc for notification actions to know more
});
}
// Schedules a push notification by a given javascript Date object
scheduleNotif(date, title, message) {
this.lastId++;
PushNotification.localNotificationSchedule({
date: date,
/* Android Only Properties */
id: '' + this.lastId,
bigText: '',
subText: '',
/* iOS and Android properties */
title: title,
message: message,
});
}
checkPermission(cbk) {
return PushNotification.checkPermissions(cbk);
}
cancelNotif() {
PushNotification.cancelLocalNotifications({ id: '' + this.lastId });
}
cancelAll() {
PushNotification.cancelAllLocalNotifications();
}
}
// ...
import BackgroundFetch from 'react-native-background-fetch';
const initBackGroundFetch = () => {
BackgroundFetch.configure(
{
minimumFetchInterval: 15, // <-- minutes (15 is minimum allowed)
// Android options
forceAlarmManager: false, // <-- Set true to bypass JobScheduler.
stopOnTerminate: false,
startOnBoot: true,
requiredNetworkType: BackgroundFetch.NETWORK_TYPE_ANY, // Network connection needed
},
async taskId => {
// Do stuff with notifications, for example:
const notificationService = new NotificationService(
() => {//... what to do on register},
() => {//... what to do on notification }
)
const date = new Date(Date.now() + 60 * 1000) // adjust according to your use case
notificationService.scheduleNotif(date, "title", "message");
BackgroundFetch.finish(taskId);
},
error => {
console.log('[js] RNBackgroundFetch failed to start');
},
);
};
const App = () => {
useEffect(() => {
initBackGroundFetch();
}, []);
return (
// ...
);
};
The NotificationService is an adjusted version of an example the react native push notification library provides found here: https://github.com/zo0r/react-native-push-notification/blob/master/example/NotifService.js.
Related
I added webRTC feature to make in app call using firebase and react native push notification. The problem is that the company wants the app to start and show the incoming call screen if the app is locked.
Is there any way to make this happen? And,Which resources I can use?
I am handling the background state using the setBackground handler provided from react-native-firebase, and the call is initialized by a push notification, which contains only data payload.
The handler is:
messaging().setBackgroundMessageHandler(async notification => {
let id = 1893950948;
console.log('#INITIAL ROUTE: ', notification);
if (notification.data.channelName === __config.BRAND_PSN_CHANNELS.RTC_CALL) {
if (notification.data.title === 'Incoming call') {
InCallManager.startRingtone('_BUNDLE_');
const {offer, name, sendingAgent} = notification.data;
PushNotification.localNotification({
id,
title: 'Incoming call',
message: `${name} is calling you`,
data: {...notification.data},
channelId: '2',
messageId: notification.messageId,
importance: 'max',
smallIcon: 'app_icon',
largeIcon: 'app_icon',
ongoing: true,
tag: 'call-user',
visibility: 'public',
actions: ['Answer', 'Decline'],
invokeApp: false,
priority: 'high',
});
// send the ringing event
axios.post(
`${API_BASE_URL}/${WEBRTC_URLS.ringingURI}/?token=${WEBRTC_URLS.webhookToken}`,
{
to: sendingAgent,
},
);
// set the data to the local storage
const storedCall = {
offer,
name,
sendingAgent,
};
// PushNotification.getDeliveredNotifications(notifications =>
// console.log(notifications),
// );
// set the data to the local storage
await AsyncStorage.setItem('storedCall', JSON.stringify(storedCall));
}
}
if (notification.data.title === 'Missed Call') {
PushNotification.removeAllDeliveredNotifications();
InCallManager.stopRingtone('_BUNDLE_');
await AsyncStorage.removeItem('storedCall');
await AsyncStorage.removeItem('notification');
}
return Promise.resolve();
});
i am able to generate notification along with action buttons but how to call a onpress event based on the button pressed by user? here yes or no
thanks in advance
import PushNotification from 'react-native-push-notification';
function configure() {
PushNotification.configure({
// (required) Called when a remote is received or opened, or local notification is opened
onNotification: function (notification) {
console.log('NOTIFICATION:', notification);
// process the notification
// (required) Called when a remote is received or opened, or local notification is opened
notification.finish();
},
// IOS ONLY (optional): default: all - Permissions to register.
permissions: {
alert: true,
badge: true,
sound: true,
},
// Should the initial notification be popped automatically
// default: true
popInitialNotification: true,
/**
* (optional) default: true
* - Specified if permissions (ios) and token (android and ios) will requested or not,
* - if not, you must call PushNotificationsHandler.requestPermissions() later
* - if you are not using remote notification or do not have Firebase installed, use this:
* requestPermissions: Platform.OS === 'ios'
*/
requestPermissions: true,
requestPermissions: Platform.OS === 'ios',
'content-available': 1,
});
}
function givenotification(title, message) {
PushNotification.localNotification({
channelId: 'channel',
message: message, // (required)
title: title,
message: message, // (required)
actions: ["Yes", "No"]
});
}
I have never used push notification directly,
for my notification i have use React Native Notifee that have this "displayNotification" inside when you try to log Notifee ..
I suggest you to try log "PushNotification" to find a function to display your notification.
You can setup the action as below code:
export const App = () => {
const [permissions, setPermissions] = useState({});
/**
* By calling this function, a notification with category `userAction` will have action buttons
*/
const setNotificationCategories = () => {
PushNotificationIOS.setNotificationCategories([
{
id: 'userAction',
actions: [
{id: 'open', title: 'Open', options: {foreground: true}},
{
id: 'ignore',
title: 'Desruptive',
options: {foreground: true, destructive: true},
},
{
id: 'text',
title: 'Text Input',
options: {foreground: true},
textInput: {buttonTitle: 'Send'},
},
],
},
]);
};
useEffect(() => {
PushNotificationIOS.addEventListener('notification', onRemoteNotification);
});
const onRemoteNotification = (notification) => {
const actionIdentifier = notification.getActionIdentifier();
if (actionIdentifier === 'open') {
// Perform action based on open action
}
if (actionIdentifier === 'text') {
// Text that of user input.
const userText = notification.getUserText();
// Perform action based on textinput action
}
};
};
For more, you can reach out to the official documentation of the library.
https://github.com/zo0r/react-native-push-notification
I am trying to send a mobile push notification to my android device based on apex trigger, and I didn't see notification banner but in console I can see onNotification event fired and I can see my payload info.
I have followed In react native app react-native-push-notification library, all changes are done as per the document mention here https://www.npmjs.com/package/react-native-push-notification.
updated MobilePushServiceDevice whenever user open the with token and service type
On FCM created the project and follow this document https://firebase.google.com/docs/cloud-messaging/android/client
Salesforce create connected enable push notification added server key
here is react code
const notification = PushNotification.configure({
// (optional) Called when Token is generated (iOS and Android)
onRegister: function (token) {
//Send this token to salesforce
let createPayload = {
ServiceType: getSystemName() == 'Android' ? 'androidGcm' : 'apple',
ConnectionToken: token.token
};
// register device with salesforce
},
// (required) Called when a remote is received or opened, or local notification is opened
onNotification: function (notification) {
console.log("NOTIFICATION:", notification);
notification.finish(PushNotificationIOS.FetchResult.NoData);
},
// (optional) Called when Registered Action is pressed and invokeApp is false, if true onNotification will be called (Android)
onAction: function (notification) {
console.log("ACTION:", notification.action);
console.log("NOTIFICATION:", notification);
// process the action
},
// (optional) Called when the user fails to register for remote notifications. Typically occurs when APNS is having issues, or the device is a simulator. (iOS)
onRegistrationError: function (err) {
console.error(err.message, err);
},
// IOS ONLY (optional): default: all - Permissions to register.
permissions: {
alert: true,
badge: true,
sound: true,
},
visibility: 'public',
// Should the initial notification be popped automatically
// default: true
popInitialNotification: true,
senderID: "1019984307481",
requestPermissions: true,
});
here is my apex code
`Messaging.PushNotification msg = new Messaging.PushNotification();
Map<String, Object> androidPayload = new Map<String, Object>();
Set<String> userSet = new Set<String>();
androidPayload.put('title', idVSnickname.get(cbuId)+' assigned you a task');
androidPayload.put('message', subject);
androidPayload.put('parentId', str[4].trim());
androidPayload.put('id', str[0].trim());
userSet.add(accIdVSuserId.get(accId));
msg.setPayload(androidPayload);
msg.send('Mimit', userSet);`
I am trying to send push notification using Expo, and I receive it. But there is no vibrate or sound and no pop up as well on my device. I am using Galaxy S9 with Android 9. I have not tried on Iphone yet.
Push notification is sent by nodejs and the user who installed the app will receive the push notification. User expo token is saved in firebase database. I succeed to save and fetch the token.
Below is from expo app
class App extends Component {
componentWillMount() {
firebase.initializeApp(config);
this.registerForPushNotificationsAsync();
}
async registerForPushNotificationsAsync(){
const { status: existingStatus } = await Permissions.getAsync(
Permissions.NOTIFICATIONS
);
let finalStatus = existingStatus;
if (Platform.OS === 'android') {
Notifications.createChannelAndroidAsync('chat-messages', {
name: 'Chat messages',
sound: true,
priority: 'high', // was max
vibrate: [0, 250, 250, 250],
});
}
if (existingStatus !== 'granted') {
const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
finalStatus = status;
}
Below is from nodejs server-side
function sendMessage(to, title, body) {
const expo = new Expo();
let messages = [];
messages.push({
to, // Expo user token
body,
data: { withSome: 'data' },
ios: {
sound: true
},
android: {
"channelId": "chat-messages" //and this
}
})
let chunks = expo.chunkPushNotifications(messages);
let tickets = [];
(async () => {
for (let chunk of chunks) {
try {
let ticketChunk = await expo.sendPushNotificationsAsync(chunk);
tickets.push(...ticketChunk);
} catch (error) {
console.error(error);
}
}
})();
}
Also could we redirect to web page when user click the push notification?
I see three problems on your backend code ( expo push notification docs for reference https://docs.expo.io/versions/latest/guides/push-notifications/):
According to the docs, there should be no ios or android properties on the request body;
sound should be either 'default' or null, instead of true;
You created the notification channel on the device, but when you send the notification, you forgot to tell which channel you are sending to.
All that said, your code that calls the expo push notifications api should look something like this:
messages.push({
to, // Expo user token
title: 'some title', //it is good practice to send title, and it will look better
body,
data: { withSome: 'data' },
priority: 'high', //to make sure notification is delivered as fast as possible. see documentation for more details
sound: true, //for iOS devices and android below 8.0
channelId: 'chat-messages', //for devices on android 8.0 and above
})
I hope this helps.
I feel like the docs at react-native-fcm are a bit of a mess and I am having a hard time figuring this out.
I currently have a production app and my android users are telling me they are not receiving notifications for events where they should be. So this is stressing me out a lot right now. On iOS everything seems fine.
In the react-native-fcm example app you can see the following:
//FCM.createNotificationChannel is mandatory for Android targeting >=8. Otherwise you won't see any notification
componentDidMount() {
FCM.createNotificationChannel({
id: 'default',
name: 'Default',
description: 'used for example',
priority: 'high'
})
}
Do I need to call FCM.createNotificationChannel()?? I mainly use remote notifications so is this relevant in any way?
Here is MY setup:
import FCM, {
FCMEvent,
NotificationType,
RemoteNotificationResult,
WillPresentNotificationResult,
} from 'react-native-fcm';
FCM.on(FCMEvent.Notification, async (notif) => {
// there are two parts of notif. notif.notification contains the notification payload, notif.data contains data payload
FCM.presentLocalNotification({
id: "new_message", // (optional for instant notification)
title: notif.fcm.title, // as FCM payload
body: notif.fcm.body, // as FCM payload (required)
sound: "default", // as FCM payload
priority: "high", // as FCM payload
click_action: "com.myapp.MyCategory", // as FCM payload - this is used as category identifier on iOS.
badge: 10, // as FCM payload IOS only, set 0 to clear badges
number: 10, // Android only
ticker: "My Notification Ticker", // Android only
auto_cancel: true, // Android only (default true)
large_icon: "ic_launcher", // Android only
icon: "ic_launcher", // as FCM payload, you can relace this with custom icon you put in mipmap
color: "blue", // Android only
vibrate: 300, // Android only default: 300, no vibration if you pass 0
wake_screen: true, // Android only, wake up screen when notification arrives
group: "group", // Android only
picture: "https://google.png", // Android only bigPicture style
ongoing: false, // Android only
my_custom_data:'my_custom_field_value', // extra data you want to throw
lights: true, // Android only, LED blinking (default false)
});
if(Platform.OS ==='ios'){
//optional
//iOS requires developers to call completionHandler to end notification process. If you do not call it your background remote notifications could be throttled, to read more about it see https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623013-application.
//This library handles it for you automatically with default behavior (for remote notification, finish with NoData; for WillPresent, finish depend on "show_in_foreground"). However if you want to return different result, follow the following code to override
//notif._notificationType is available for iOS platfrom
switch(notif._notificationType){
case NotificationType.Remote:
notif.finish(RemoteNotificationResult.NewData) //other types available: RemoteNotificationResult.NewData, RemoteNotificationResult.ResultFailed
break;
case NotificationType.NotificationResponse:
notif.finish();
break;
case NotificationType.WillPresent:
notif.finish(WillPresentNotificationResult.All) //other types available: WillPresentNotificationResult.None
break;
}
}
});
FCM.on(FCMEvent.RefreshToken, (token) => {
try {
const { currentUser } = firebase.auth();
let updates = {};
updates[`/allUsers/serviceUsers/${currentUser.uid}/userInfo/fcmToken`] = token;
return firebase.database().ref().update(updates).catch(err => console.log('fcm refresh error', err))
} catch (e) {
console.log('couldnt update fcm refresh token', e)
}
});
const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));
class App extends Component {
componentWillMount() {
let config = {configgg}
!firebase.apps.length ? firebase.initializeApp(config) : firebase.app();
FCM.requestPermissions();
}
render() {
return (
<Provider store={store}>
<Router/>
</Provider>
);
}
}
export default App;
I mainly use remote notifications and it is critical for my app for it to work. Is there anything I am missing in my setup?
Any hint or suggestions will help me out a lot! Thanks!
EDIT:
Found this in adb logcat when receiving a notification (that did not show up)
NotificationService: No Channel found for pkg=com.lisdoworker, channelId=null, id=0, tag=GCM-Notification:9015992, opPkg=com.lisdoworker, callingUid=10487, userId=0, incomingUserId=0, notificationUid=10487, notification=Notification(channel=null pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x10 color=0x00000000 vis=PRIVATE)
Does this have to do with FCM.createNotificationChannel()??
Yeah, apparently createNotificationChannel was added in version 16 to support Android 8 and it is barely documented.