so I've been trying to do this app but for some reason, after I can't seem to be able to detect notification from the firebase consol when the app is closed (not in the background or frontground those work fine).
so here are some of the relevant files.
componentDidMount() {
this.notificationDisplayedListener = firebase.notifications().onNotificationDisplayed((notification: Notification) => {
// Process your notification as required
// ANDROID: Remote notifications do not contain the channel ID. You will have to specify this manually if you'd like to re-display the notification.
});
this.notificationListener = firebase.notifications().onNotification((notification: Notification) => {
// Process your notification as required
notification.android.setChannelId('test-channel')
console.log("I'm called haha", notification);
firebase.notifications().displayNotification(notification)
});
this.messageListener = firebase.messaging().onMessage((message) => {
bgMessaging(message)
})
}
componentWillUnmount() {
this.notificationDisplayedListener();
this.notificationListener();
}
android manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mobalib">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application
android:name=".MainApplication"
android:label="#string/app_name"
android:icon="#mipmap/ic_launcher"
android:allowBackup="false"
android:theme="#style/AppTheme">
<service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
<receiver android:name="io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionReceiver"
android:exported="true">
<intent-filter>
<action android:name="io.invertase.firebase.notifications.BackgroundAction"/>
</intent-filter>
</receiver>
</service>
<service
android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<activity
android:launchMode="singleTop"
android:name=".MainActivity"
android:label="#string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>
index.js:
AppRegistry.registerHeadlessTask('RNFirebaseBackgroundMessage', () => bgMessaging);
and finaly bgMesseging.js:
xport default (message: RemoteMessage) => {
// handle your message
const title = message.get
const notification = new firebase.notifications.Notification()
.setNotificationId('notificationId')
.setTitle('My notification title')
.setBody('My notification body')
.setData({
key1: 'value1',
key2: 'value2',
});
notification
.android.setChannelId('test-channel')
firebase.notifications().displayNotification(notification)
console.log(message);
return Promise.resolve();
}
the TL/dr is that depending on what brand your phone is the notification can only be detected.
so Android not that great when it comes to this part of notification but it is so customisable on other thing that i do like it
Related
I have used react-native-push-notification package. But onNotification callback method does not call when the app is closed but it works fine when the app is in the background or on foreground.
I have also changed <category android:name="android.intent.category.DEFAULT" /> with <category android:name="android.intent.category.INFO" /> but it did not work.
Here is AndroidMenifest.xml file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.appname">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application android:name=".MainApplication" android:label="#string/app_name" android:icon="#mipmap/logo" android:roundIcon="#mipmap/logo_round" android:allowBackup="false" android:usesCleartextTraffic="false" android:theme="#style/AppTheme" android:networkSecurityConfig="#xml/network_security_config">
<activity android:name=".SplashActivity" android:theme="#style/SplashTheme" android:label="#string/app_name" android:screenOrientation="portrait" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity" android:label="#string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:screenOrientation="portrait" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.INFO" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="appname" />
</intent-filter>
</activity>
<meta-data android:name="com.dieam.reactnativepushnotification.default_notification_channel_id" android:value="#string/default_notification_channel_id" />
<!-- Change the value to true to enable pop-up for in foreground on receiving remote notifications (for prevent duplicating while showing local notifications set this to false) -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground" android:value="true"/>
<!-- Change the resource name to your App's accent color - or any other color you want -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color" android:resource="#color/white"/>
<!-- or #android:color/{name} to use a standard color -->
<!-- Notification icon -->
<meta-data android:name = "com.dieam.reactnativepushnotification.notification_icon" android:resource="#mipmap/ic_launcher" />
<meta-data android:name = "com.google.firebase.messaging.default_notification_icon" android:resource="#mipmap/ic_launcher" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>
</receiver>
<service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService" android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
you need to used firebase messaging
messaging().setBackgroundMessageHandler(async (remoteMessage) => {
console.log('Your message was handled in background');
});
for more information you need to prefer this link :- https://rnfirebase.io/messaging/usage
I am using dynamic link in React Native, I have all the steps required for IOS and android setup. (dynamic link opens the app on both platform) but when I have deep link attached to it, on Android app is opened but deep link parameters are not passed.
IOS works fine, deep link works correctly.
"react-native": "0.67.4",
"#react-native-firebase/app": "12.7.4",
"#react-native-firebase/dynamic-links": "12.7.4",
device: Xiaomi mi 9,
browser: Xiaomi browser,
deeplink: https://sweeftdigital.page.link/transfer_tip?userId=3
deep link debug version
video
Press to see video
In this video there are two browser: Mi browser and chrome browser,
Mi browser: when pressing dynamic link, it opens app directly without passing parameters.
chrome: when pressing dynamic link, it asks to open either in browser or open app, when you choose and app it passes parameters and deep link works.
AndroidManifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tipapp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
<application android:name=".MainApplication"
android:label="#string/app_name"
android:icon="#mipmap/ic_launcher"
android:allowBackup="false"
android:usesCleartextTraffic="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity"
android:exported='true'
android:label="#string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
</intent-filter>
<intent-filter >
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "https://www.sweeftdigital.page.link/” -->
<data android:scheme="https"
android:host="sweeftdigital.page.link" />
<!-- Accepts URIs that begin with "tipapp://” -->
<data android:scheme="tipapp" />
</intent-filter>
</activity>
</application>
</manifest>
deep link handling with react navigation
const config = {
screens: {
webView: {
path: '/transfer_tip',
parse: {
userId: (userId: any) => userId,
},
},
authLoading: '*',
},
};
const linking = {
prefixes: ['tipapp://', 'https://sweeftdigital.page.link'],
config: config,
};
<NavigationContainer
linking={linking}
...
Is there anything incorrect or is it firebase dynamic links normal behaviour?
when i set the alarm its working when app is open when i schedule the alarm and close the app its not working. I try on physical devices Android 11 but its not working.
Android Mainfiest code
<application
android:name=".MainApplication"
android:label="#string/app_name"
android:icon="#mipmap/ic_launcher"
android:roundIcon="#mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.emekalites.react.alarm.notification.ANService" android:enabled="true"/>
<receiver
android:name="com.emekalites.react.alarm.notification.AlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="ACTION_DISMISS" />
<action android:name="ACTION_SNOOZE" />
</intent-filter>
</receiver>
<receiver
android:name="com.emekalites.react.alarm.notification.AlarmDismissReceiver"
android:enabled="true"
android:exported="true" />
<receiver
android:name="com.emekalites.react.alarm.notification.AlarmBootReceiver"
android:directBootAware="true"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
Schedule alarm
const alarmNotifData = {
title: 'Alarm Ringing', // Required
message: this.state.name, // Required
channel: 'alarm-channel', // Required. Same id as specified in MainApplication's onCreate method
ticker: 'My Notification Ticker',
auto_cancel: true, // default: true
vibrate: true,
vibration: 100, // default: 100, no vibration if vibrate: false
small_icon: 'ic_launcher', // Required
large_icon: 'ic_launcher',
play_sound: true,
sound_name: null, // Plays custom notification ringtone if sound_name: null
color: 'red',
schedule_once: true, // Works with ReactNativeAN.scheduleAlarm so alarm fires once
// tag: 'some_tag',
};
var alarm_id;
if (!isother) {
try {
alarm_id = await ReactNativeAN.scheduleAlarm({ ...alarmNotifData, fire_date: fireDate });
} catch (error) {
alert(error)
}
when i set the alarm its working when app is open when i schedule the alarm and close the app its not working
package.js
"#react-native-firebase/database": "^14.2.2",
"#react-native-firebase/messaging": "^14.2.2",
"#react-navigation/native": "^6.0.6",
"#react-navigation/stack": "^6.0.11",
"install": "^0.13.0",
"npm": "^8.3.0",
"react": "17.0.2",
"react-native": "0.66.4",
"react-native-alarm-notification": "^1.8.0",
I was read when you want show if app closed , you have to call that in background app refresh in android , you have to set push notification and this show even app closed , for android you can use firebase push notification and for ios basically use Apns or firebase too. for more info see this
I have used react-native-firebase in my react native project[android platform] to show the app notification. With this library i am able to show the notification when the app is in the foreground/background/closed state.
According to the react native firebase documentation the onNotificationOpened should be triggered when the app is opened by the notification tap. However this is not happening in my case, the onNotificationOpened method is never called and getInitialNotification method always gets a null value.
I am also using react-native-splash-screen library to display the splashscreen.
Here's my code from App.js >> componentDidMount()
firebase.messaging().requestPermission()
.then(() => {
const myAppChannel = new firebase.notifications.Android.Channel('my-channel',
'my Channel', firebase.notifications.Android.Importance.Max)
.setDescription('my channel');
firebase.notifications().android.createChannel(myAppChannel);
this.messageListener = firebase.messaging().onMessage((message) => {
const {title, body} = message.data;
const notificationDisplay = new firebase.notifications.Notification()
.setNotificationId('notificationId')
.setTitle(title)
.setBody(body)
.setData({
key1: 'value1',
key2: 'value2',
}).setSubtitle('notification')
.setSound('default');
notificationDisplay
.android.setChannelId('my-channel')
.android.setSmallIcon('ic_launcher')
.android.setAutoCancel(true).android.setPriority(firebase.notifications.Android.Priority.High);
firebase.notifications().displayNotification(notificationDisplay);
});
this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen: NotificationOpen) => {
//never gets called
console.log('onNotificationOpened was triggered on notification taped');
});
})
.catch(error => {
// User has rejected permissions
console.log("user rejected");
console.log(error);
});
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:name=".MainApplication"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service android:name="io.invertase.firebase.messaging.RNFirebaseBackgroundMessagingService" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="#string/default_notification_channel_id" />
<activity
android:name=".SplashActivity"
android:label="#string/app_name"
android:launchMode="singleTop"
android:theme="#style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:exported="true"
android:label="#string/app_name"
android:launchMode="singleTop"
android:windowSoftInputMode="adjustResize" />
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
UPDATE: Problem was caused by the react-native-splash-screen library, I was able to fix this after removing the react-native-splash-screen library from the android project. However i am still not sure how i can make this work when using the react-native-splash-screen.
Adding intent-filter to MainActivity and click-action to notification JSON did the trick for me.
<intent-filter>
<action android:name=".MainActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Notification JSON
{
"to":"ID",
"notification" : {
**"click_action" : ".MainActivity",**
"body": "Message Body",
"title" : "Call Status",
"sound": "default",
"badge":"5"
},
"data": {
"type": 1,
"body": "Message Body",
"title" : "Call Status"
}
}
My manifest.xml looks like this
<application
tools:replace="android:allowBackup"
android:name=".MainApplication"
android:label="#string/app_name"
android:icon="#mipmap/ic_launcher"
android:allowBackup="false"
android:theme="#style/AppTheme">
<service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<activity
android:name=".SplashActivity"
android:theme="#style/SplashTheme"
android:launchMode="singleTop"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:launchMode="singleTop"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name=".MainActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
Hope this helps
I have a problem with the splashscreen on Android. Here is everything what I am doing:
Creating background_splash.xml file:
xml version="1.0" encoding="utf-8"?>
layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="#android:color/darker_gray"/>
<item>
<bitmap
android:gravity="center"
android:src="#drawable/splash"/>
</item>
I remove < in the first two lines because stackoverflow cannot display them. This file is located in drawable.
I added the following to styles.xml:
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">#drawable/background_splash</item>
</style>
and this is my manifest files:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="22" />
<application
android:name=".MainApplication"
android:allowBackup="true"
android:label="#string/app_name"
android:icon="#mipmap/ic_launcher"
android:theme="#style/AppTheme">
<activity
android:name=".SplashActivity"
android:label="#string/app_name"
android:theme="#style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity" />
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>
And also the activity:
import android.content.Intent;
import android.os.Bundle;
import com.facebook.react.ReactActivity;
public class SplashActivity extends ReactActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
}
This is the error I have:
Starting the app on 51d123cc (adb -s 51d123cc shell am start -n com.test/.MainActivity)...
Starting: Intent { cmp=com.test/.MainActivity }
java.lang.SecurityException: Permission Denial: starting Intent { flg=0x10000000 cmp=com.test/.MainActivity } from null (pid=20601, uid=2000) not exported from uid 11152
at android.os.Parcel.readException(Parcel.java:1540)
at android.os.Parcel.readException(Parcel.java:1493)
at android.app.ActivityManagerProxy.startActivityAsUser(ActivityManagerNative.java:2589)
at com.android.commands.am.Am.runStart(Am.java:768)
at com.android.commands.am.Am.onRun(Am.java:307)
at com.android.internal.os.BaseCommand.run(BaseCommand.java:47)
at com.android.commands.am.Am.main(Am.java:102)
at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:255)
UPDATE:
To the answer of #Ankit Prajapati I will add also that I set
android:largeHeap="true"
which was an error from Android Studio (running from the terminal this error wasn't reported) and this happen after changing activity to SplashActivity.
Also it was necessary to change edit configurations and changing "Launch Activity" to "Specified Activity" and setting com.test.SplashActivity.
Second way of managing splash screen on Android and which I use right now is with this tutorial:
Splash Screen Android
Try using this in
android:exported="true" in the manifest file in the activity you are trying to start (Loading Activity)
Like this
<activity
android:name=".SplashActivity"
android:label="#string/app_name"
android:theme="#style/SplashTheme"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Also Add
Intent intent = new Intent(SplashActivity.this, MainActivity.class);