Open juaan opened 6 years ago
you shouldn't need to. Are you experience those issue with example project?
Turns out it worked! I tried to send it manually from firebase console and it worked. The problem is my BE send data message
notification type, instead of the default notification type. Could you please elaborate How to handle this data message notification type @evollu ?
In most cases, you should send iOS notifications with notification body. I remember reading somewhere that iOS is blocking data only notification in latest OS (I haven't validated yet).
How to handle this data message notification type
are you trying to do something with data only message?
Yup, from what I read if it is data message, client need to do something to process the notification,
So i use fcm.showLocalNotificarion and it worked in foreground the notfication tray is popped, but when in background the notification tray didnt pop
Above is the object data message that I got from BE, its different with notification message @evollu
have you added background push capability in xcode?
again, iOS should use notificatoin
property to deliver reliably. Can you get what your BE is posting to firebase?
im still requesting from my BE engineer... @evollu
import { Platform, AsyncStorage, AppState } from 'react-native';
import FCM, {FCMEvent, RemoteNotificationResult, WillPresentNotificationResult, NotificationType, NotificationActionType, NotificationActionOption, NotificationCategoryOption} from "react-native-fcm";
import { pushNotifications } from '../services';
AsyncStorage.getItem('lastNotification').then(data=>{ if(data){ // if notification arrives when app is killed, it should still be logged here console.log('last notification', JSON.parse(data)); AsyncStorage.removeItem('lastNotification'); } })
AsyncStorage.getItem('lastMessage').then(data=>{ if(data){ // if notification arrives when app is killed, it should still be logged here console.log('last message', JSON.parse(data)); AsyncStorage.removeItem('lastMessage'); } }) const showLocalNotification = (data) => { FCM.presentLocalNotification({ id: new Date().valueOf().toString(), // (optional for instant notification) title: data.title, // as FCM payload body: data.body, // as FCM payload (required) sound: "bell.mp3", // "default" or filename priority: "high", // as FCM payload click_action: "com.myapp.MyCategory", // as FCM payload - this is used as category identifier on iOS. badge: 0, // as FCM payload IOS only, set 0 to clear badges icon: "ic_launcher", // as FCM payload, you can relace this with custom icon you put in mipmap show_in_foreground: true, // notification when app is in foreground (local & remote) opened_from_tray: 1 }); }
export function registerKilledListener(){ // these callback will be triggered even when app is killed FCM.on(FCMEvent.Notification, notif => { AsyncStorage.setItem('lastNotification', JSON.stringify(notif)); if(notif.opened_from_tray){ setTimeout(()=>{ if(notif._actionIdentifier === 'reply'){ if(AppState.currentState !== 'background'){ console.log('User replied '+ JSON.stringify(notif._userText)) alert('User replied '+ JSON.stringify(notif._userText)); } else { AsyncStorage.setItem('lastMessage', JSON.stringify(notif._userText)); } } if(notif._actionIdentifier === 'view'){ alert("User clicked View in App"); } if(notif._actionIdentifier === 'dismiss'){ alert("User clicked Dismiss"); } }, 1000) } }); }
// these callback will be triggered only when app is foreground or background
export function registerAppListener(navigation){
FCM.on(FCMEvent.Notification, notif => {
console.log("Notification", notif);
// showLocalNotification(notif)
notif.finish(WillPresentNotificationResult.All)
if (notif.label) showLocalNotification(notif)
if(notif.opened_from_tray){
switch (notif.label) {
case 'timeslots_ending':
setTimeout(()=>{
navigation.navigate('TimeslotList')
}, 500)
break;
case 'confirm_meet':
setTimeout(()=>{
navigation.navigate('TimeslotList')
}, 500)
break;
default:
setTimeout(()=>{
navigation.navigate('YourBids')
}, 500)
break;
}
}
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 the above documentation link.
//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
// showLocalNotification(notif);
break;
case NotificationType.NotificationResponse:
notif.finish();
// showLocalNotification(notif);
break;
case NotificationType.WillPresent:
notif.finish(WillPresentNotificationResult.All);
// showLocalNotification(notif);
//other types available: WillPresentNotificationResult.None
// this type of notificaiton will be called only when you are in foreground.
// if it is a remote notification, don't do any app logic here. Another notification callback will be triggered with type NotificationType.Remote
break;
default:
notif.finish(WillPresentNotificationResult.All);
// showLocalNotification(notif);
break;
}
}
});
FCM.on(FCMEvent.RefreshToken, token => { console.log("TOKEN (refreshUnsubscribe)", token); });
FCM.enableDirectChannel(); FCM.on(FCMEvent.DirectChannelConnectionChanged, (data) => { console.log('direct channel connected ' + data); }); setTimeout(function() { FCM.isDirectChannelEstablished().then(d => console.log(d)); }, 1000); }
FCM.setNotificationCategories([ { id: 'bundle', actions: [ { type: NotificationActionType.TextInput, id: 'reply', title: 'Quick Reply', textInputButtonTitle: 'Send', textInputPlaceholder: 'Say something', intentIdentifiers: [], options: NotificationActionOption.AuthenticationRequired }, { type: NotificationActionType.Default, id: 'view', title: 'View in App', intentIdentifiers: [], options: NotificationActionOption.Foreground }, { type: NotificationActionType.Default, id: 'dismiss', title: 'Dismiss', intentIdentifiers: [], options: NotificationActionOption.Destructive } ], options: [NotificationCategoryOption.CustomDismissAction, NotificationCategoryOption.PreviewsShowTitle] } ])
- ## And this is how I call the listener
import {registerKilledListener, registerAppListener} from "./firebaseListener";
registerKilledListener(); class Nearby extends Component { .......
async componentDidMount() {
registerAppListener(this.props.navigation);
FCM.getInitialNotification().then(notif => {
this.setState({
initNotif: notif
});
if (notif && notif.label === 'new_bid'){
setTimeout(()=>{
this.props.navigation.navigate('YourBids')
}, 500)
};
});
if (this.props.logindata.userdata) {
try{
let result = await FCM.requestPermissions({badge: false, sound: true, alert: true});
} catch(e){
console.error(e);
}
FCM.getFCMToken().then(token => {
console.log("TOKEN (getFCMToken)", token);
this.props.registerFirebase({memberId: member_id, token})
});
}
} }
your code seems fine BTW, you won't need following code if you are not doing special logic
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 the above documentation link.
//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
// showLocalNotification(notif);
break;
case NotificationType.NotificationResponse:
notif.finish();
// showLocalNotification(notif);
break;
case NotificationType.WillPresent:
notif.finish(WillPresentNotificationResult.All);
// showLocalNotification(notif);
//other types available: WillPresentNotificationResult.None
// this type of notificaiton will be called only when you are in foreground.
// if it is a remote notification, don't do any app logic here. Another notification callback will be triggered with type NotificationType.Remote
break;
default:
notif.finish(WillPresentNotificationResult.All);
// showLocalNotification(notif);
break;
}
}
});
hmmm what do you mean by special logic?
then again the notif still not showing when in background mode. am I doing it right?
do FCM.presentLocalNotification
also make the notification show when the app is in background ?
@evollu
do FCM.presentLocalNotification also make the notification show when the app is in background ?
not after going back to background for a while
@evollu Having somewhat similar issues, and since this wasnt closed figured I would add comment here rather than create a new issues unless/until i find out more.
my current version: react-native : 0.51.1 react-native-fcm : 13.3.1
I want to let people send messages via the push notification without brining the app to the foreground. (from killed or background state usually). I am having trouble being able to use the reply action consistently. I am using your example and specifically NotificationActionType.TextInput
when calling setNotificationCategories
. Everything seems to work fine as far as receiving a push and then opening it and typing a response. The FIRST time this happens and I reply, I get the expected behavior of an _actionIdentifier
and expected _userText
on the notification object.
However, things break down on the SECOND attempt at the same action being completed. Instead of the repeated previous behavior, nothing happens. It is almost as if the first action blocked or errored out perhaps. Only if I explicitly open the app and bring to the foreground does the intended action complete itself (for example: say userA and userB are having a conversation and many back and forth messages are happening via push. This wont support that without bringing app to foreground.)
Note that if I set the action options to NotificationActionOption.Foreground
when calling setNotificationCategories
everything works as expected, but it forces the app to the foreground each time a reply action is made. I desire to avoid that since it negates the convenience of not having to open the app in foreground to respond.
Question: Curious on how you make it so that the "AppKilledListener" one only fires when app is killed and not when app is in foreground. When I set it up they would both be fired in foreground since they are listening to same event but I just have to use logic know the state. Maybe that is an issue?
@temitope you might need to dig into the native code and see what is going on. Things might worth checking:
@evollu i will take a closer look. thanks. For clarity
Thanks.
Hi, I'm trying to implement the example that is in this repo, to my project. I'm handling the Listener's side. I get the notification, but some of the properties is undefined, like _notificationType, opened_from_tray and local_notification.
And some problem also happen the notification tray didn't pop up, unless I use FCM.presentLocalNotification. should I use that method even I want to catch the remote notification?
my current version:
RN : 0.51.0 RN-FCM : 14.1.2