I created a Dynamic link through createDynamicLink that is inside the class DynamicLinkService, after this I use retrieveDynamicLink for the part of reading the link that is opened from the android browser, but it prints that it is null, therefore it does not enter the if and does not push to another route inside the if
class DynamicLinkService {
Future<void> retrieveDynamicLink(BuildContext context) async {
try {
final PendingDynamicLinkData? data =
await FirebaseDynamicLinks.instance.getInitialLink();
final Uri? deepLink = data?.link;
print("deepLink: $deepLink");
if (deepLink != null) {
print("deepLink If: $deepLink");
String deepLinks = deepLink.toString();
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => linkInvitacionScreen(deepLinks)));
}
} catch (e) {
print(e.toString());
}
}
Future<String> createDynamicLink(String groupID) async {
final DynamicLinkParameters parameters = DynamicLinkParameters(
uriPrefix: 'https://notforget.page.link/',
link: Uri.parse(
'https://notforget.com/groupid?$groupID'),
androidParameters: const AndroidParameters(
packageName: 'com.example.not_forget_flutter',
minimumVersion: 1,
),
);
final ShortDynamicLink shortDynamicLink =
await FirebaseDynamicLinks.instance.buildShortLink(parameters);
final Uri shortUrl = shortDynamicLink.shortUrl;
print(shortUrl);
return shortUrl.toString();
}
}
intent filter of AndroidManifest
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="#style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<!-- Deep linking -->
<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" android:host="notforget.page.link" />
<data android:scheme="https" />
</intent-filter>
</activity>
i tried various solutions but none led me to get a value in deeplink, what am i doing wrong?, thanks.
Replace Your Host From android:host="notforget.page.link" To android:host="notforget.page.link"
Related
I followed twitter_login plugin guide but I always get error. Specifically the TwitterLoginStatus.error is true and the authentication process ends of course. Here is my code:
Future signInWithTwitter() async {
// Create a TwitterLogin instance
final twitterLogin = TwitterLogin(
apiKey: 'xxxxxxxxx',
apiSecretKey: 'xxxxxxxxxxxxxxxxxxxx',
redirectURI: 'my-app://');
final authResult = await twitterLogin.login();
switch (authResult.status) {
case TwitterLoginStatus.loggedIn:
// success
print("succ");
return await FirebaseAuth.instance.signInWithCredential(
TwitterAuthProvider.credential(
accessToken: authResult.authToken!,
secret: authResult.authTokenSecret!,
),
);
break;
case TwitterLoginStatus.cancelledByUser:
// cancel
print("cancel");
break;
case TwitterLoginStatus.error:
// error
print("error");
break;
default:
print("def");
break;
}
}
AndroidManifest.xml:
<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 "example://gizmosā -->
<!-- Registered Callback URLs in TwitterApp -->
<data android:scheme="my-app" /> <!-- host is option -->
</intent-filter>
And also I have included the updated callback in the Twitter Developer portal:
Lastly I use twitter_login: ^4.1.0 but I have also tried with 4.0.1
I updated the Firebase messaging code in my app which has changed a lot with the recent version. A nice thing is the possibility to see the push message also in the foreground, using local notifications. Now everything works for me when the app is closed, when the app is in the background. When the app is in the foreground it works on iOS but not Android.
I followed the instructions. Added custom channel on Manifest.
I'll give you my code. If you tell me where I went wrong I'm grateful.
The Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.carlosacchetti.push_notification_example">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="push_notification_example"
android:icon="#mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="#style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="#drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<!-- <intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter> -->
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<!-- A custom Android Notification Channel to deliver FCM notifications on a non-default channel -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="high_importance_channel" />
</application>
</manifest>
The "main"
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
await Firebase.initializeApp();
print('Handling a background message ${message.messageId}');
}
/// Create a [AndroidNotificationChannel] for heads up notifications
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
'This channel is used for important notifications.', // description
importance: Importance.max,
);
/// Initialize the [FlutterLocalNotificationsPlugin] package.
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// Set the background messaging handler early on, as a named top-level function
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
/// Create an Android Notification Channel.
///
/// We use this channel in the `AndroidManifest.xml` file to override the
/// default FCM channel to enable heads up notifications.
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
/// Update the iOS foreground notification presentation options to allow
/// heads up notifications.
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
runApp(MyApp());
}
The "HomePage"
#override
void initState() {
FirebaseMessaging.instance
.getInitialMessage()
.then((RemoteMessage message) {
if (message != null) {
// Navigator.pushNamed(context, '/message',
// arguments: MessageArguments(message, true));
}
});
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification notification = message.notification;
AndroidNotification android = message.notification?.android;
if (notification != null && android != null) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channel.description,
// TODO add a proper drawable resource to android, for now using
// one that already exists in example app.
icon: 'launch_background',
),
));
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print('A new onMessageOpenedApp event was published!');
// Navigator.pushNamed(context, '/message',
// arguments: MessageArguments(message, true));
});
super.initState();
}
Where is the error that it does not allow foreground notifications in Android?
I'm trying to use FCM messaging and keep getting this error.
E/FlutterFcmService( 3684): Fatal: failed to find callback
Below is the code I've used to setup.
static Future<void> messagePiper(
Map<String, dynamic> message,
FilteredMap<String, ChatMessage> globalChatEntryMap,
FilteredMap<String, ChatMessage> gameChatEntryMap,
Subject<List<ChatMessage>> globalChatSubject,
Subject<List<ChatMessage>> gameChatSubject,
Map<String, Player> _playerMap) async {
final Map<String, dynamic> data = message['data'];
if (data.containsKey('name')) {
final msg = ChatMessage.fromMap(data);
globalChatEntryMap.putIfAbsent(msg.id, () => msg);
globalChatSubject.add(globalChatEntryMap.values.toList());
} else {
final msg = GameChatMessage.fromMap(data);
final chat = ChatMessage.fromGlobalChatMessage(
msg,
_playerMap[msg.pId].name,
_playerMap[msg.pId].imageUrl,
);
print('chat: $chat');
gameChatEntryMap.putIfAbsent(msg.id, () => chat);
print('_gameChatEntryMap : $gameChatEntryMap');
gameChatSubject.add(gameChatEntryMap.values.toList());
}
return Future<void>.value();
}
is the callback passed in to FirebaseMessaging configuration.
final FirebaseMessaging _fm = FirebaseMessaging();
#override
void initState() {
_fm.configure(
onMessage: (Map<String, dynamic> message) async {
print('onMessagee : $message');
return Utils.messagePiper(
message,
_globalChatEntryMap,
_gameChatEntryMap,
_globalChatSubject,
_gameChatSubject,
_playerMap);
},
onLaunch: (Map<String, dynamic> message) async {
print('onLaunch : $message');
return Utils.messagePiper(
message,
_globalChatEntryMap,
_gameChatEntryMap,
_globalChatSubject,
_gameChatSubject,
_playerMap);
;
},
onResume: (Map<String, dynamic> message) async {
print('onResume : $message');
return Utils.messagePiper(
message,
_globalChatEntryMap,
_gameChatEntryMap,
_globalChatSubject,
_gameChatSubject,
_playerMap);
;
},
onBackgroundMessage: null);
....
Java configuration file
package io.flutter.plugins;
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService;
public class Application extends FlutterApplication implements PluginRegistrantCallback {
#Override
public void onCreate() {
super.onCreate();
FlutterFirebaseMessagingService.setPluginRegistrant(this);
}
#Override
public void registerWith(PluginRegistry registry) {
GeneratedPluginRegistrant.registerWith(registry);
}
}
dependency versions
random_string: 0.0.2
firebase_auth: ^0.14.0+5
firebase_database: ^3.0.7
provider: 3.0.0
rxdart: ^0.22.2
collection: ^1.14.11
audioplayers: ^0.13.2
firebase_admob: ^0.5.5
connectivity: ^0.4.4
firebase_messaging: ^5.1.6 # tried with several different versions
I tried with several firebase_messaging versions but couldn't find a fix.
Appreciate any help to solve this issue.
This error message is coming from startBackgroundIsolate which is used for allowing handling background messages.
If you don't want to handle background messages then you can safely ignore this error message. Otherwise, you need to set up a callback for handling background messages as described here
If your callback is not executed when clicking on the notification then it's because you didn't set click_action property of the message to FLUTTER_NOTIFICATION_CLICK
Are you sending FCM using the web, not FCM console?
make sure the post request is correct on your backend. I'm using Laravel
$response = Http::withHeaders([
'Content-Type' => 'application/json',
'Authorization'=> 'key='. $token,
])->post($url, [
'notification' => [
'body' => $request->summary,
'title' => $request->title,
'image' => request()->getHttpHost().$path,
],
'priority'=> 'high',
'data' => [
'click_action'=> 'FLUTTER_NOTIFICATION_CLICK',
'status'=> 'done',
],
'to' => '/topics/all'
]);
You should declare a backgroundMessageHandler function that is outside a class or as a static function, in order to be reached from outside, and then you pass this function to fbm.configure:
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) {
print('on background $message');
}
fbm.configure(
onMessage: (msg) {
print(msg);
return;
},
onLaunch: (msg) {
print(msg);
return;
},
onResume: (msg) {
print(msg);
return;
},
onBackgroundMessage: myBackgroundMessageHandler
);
Also open your_project_folder/android/app/source/AndroidManifest.xml and paste this XML code after existing intent-filter code of your main Activity:
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
The result will be similar to the following code:
<activity android:name=".MainActivity" android:launchMode="singleTop" android:theme="#style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
In Application class use the below code
previously it was GeneratedPluginRegistrant.registerWith(registry);,
replace it with
FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService;
public class Application extends FlutterApplication implements PluginRegistrantCallback {
#Override
public void onCreate(){
super.onCreate();
FlutterFirebaseMessagingService.setPluginRegistrant(this);
}
#Override
public void registerWith(PluginRegistry registry){
FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
}
}
When I was trying to send a notification from the firebase console just to test my app receives notifications, I also encountered the same error. Make sure you kill the app on your emulator so it is not running in the background. And now try sending a notification from the firebase console, wait for a couple of seconds and you should see it. This worked for me.
I am integrating firebase push notification in my app using react-native-firebase https://github.com/invertase/react-native-firebase.
I am able to receive notification in all conditions - i. app in foreground, ii. app in background or iii. app in killed state, however I am unable to launch my application on tap of notification in android. In iOS, app is getting launched on tap of notification, as expected.
I have gone through follow links :
https://github.com/rohitmodi12/firebasePushnotificaiton/issues/1
https://github.com/invertase/react-native-firebase-docs/blob/master/docs/notifications/receiving-notifications.md
https://github.com/rohitmodi12/firebasePushnotificaiton/blob/master/FirebaseNotifiction/App.js
Here is related code snippet :
'channelId',
'Channel Name',
firebase.notifications.Android.Importance.Max
).setDescription('A natural description of the channel');
firebase.notifications().android.createChannel(channel);
// the listener returns a function you can use to unsubscribe
this.unsubscribeFromNotificationListener = firebase.notifications().onNotification((notification) => {
if (Platform.OS === 'android') {
const localNotification = new firebase.notifications.Notification({
sound: 'default',
show_in_foreground: true,
})
.setNotificationId(notification.notificationId)
.setTitle(notification.title)
.setSubtitle(notification.subtitle)
.setBody(notification.body)
.setData(notification.data)
.android.setChannelId('channelId')
.android.setPriority(firebase.notifications.Android.Priority.High)
firebase.notifications()
.displayNotification(localNotification)
.catch(err => console.log(err));
} else if (Platform.OS === 'ios') {
const localNotification = new firebase.notifications.Notification()
.setNotificationId(notification.notificationId)
.setTitle(notification.title)
.setSubtitle(notification.subtitle)
.setBody(notification.body)
.setData(notification.data)
.ios.setBadge(notification.ios.badge);
firebase.notifications()
.displayNotification(localNotification)
.catch(err => console.log(err));
}
});
Declared in Manifiest.xml
<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.RNFirebaseBackgroundMessagingService" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#mipmap/ic_launcher" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/notificationColor" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="#string/default_notification_channel_id"/>
<receiver android:name="io.invertase.firebase.notifications.RNFirebaseNotificationReceiver"/>
<receiver android:enabled="true" android:exported="true" android:name="io.invertase.firebase.notifications.RNFirebaseNotificationsRebootReceiver">
<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"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Firebase Configuration
apiKey: "AZzasaSy7876456456j4qrzSuU5q",
authDomain: "xyz.firebaseapp.com",
databaseURL: "https://xyz.firebaseio.com",
projectId: "xyz",
storageBucket: "xyz.appspot.com",
messagingSenderId: "12321342142"
};
if (!firebase.apps.length) {
firebase.initializeApp(config);
}
Dependencies :
"dependencies": {
"firebase": "^5.0.3",
"lodash": "^4.17.11",
"prop-types": "^15.6.2",
"react": "16.4.1",
"react-native": "0.56.0",
"react-native-elements": "^0.19.1",
"react-native-firebase": "^5.3.1",
"react-native-iphone-x-helper": "^1.2.0",
"react-native-keyboard-aware-scroll-view": "^0.8.0",
"react-native-loading-spinner-overlay": "^1.0.1",
"react-native-modal-datetime-picker": "^7.4.0",
"react-native-navigation": "^2.3.0",
"react-native-secure-key-store": "^2.0.2",
"react-native-segmented-control-tab": "^3.3.1",
"react-native-size-matters": "^0.2.1",
"react-native-svg": "6.5.3",
"react-native-svg-charts": "^5.2.0",
"react-native-tabbar-bottom": "^1.0.4",
"react-native-vector-icons": "^6.1.0",
"react-redux": "^6.0.0",
"redux": "^4.0.1"
},
Am I missing anything over here? Please suggest.
I started with React Native recently, and it comes up that I had to use Push Notifications to notify all the users when a certain action is triggered,
so alright, I read the Firebase docs, configured the project, installed the dependencies, and I think that I've done everything alright, but my application closes when I try to send any notification to the app, and it's driving me crazy, because I haven't seen any other post with this problem yet, and I simply don't have the less idea on how to correct it, my deadline is coming, I'm gonna let all the configuration files here for you guys, and the actual code that handles the notification, even though it still does just a console.warn() on the message.
The app/build.gradle file:
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.watcher"
minSdkVersion 23
targetSdkVersion 27
versionCode 1
versionName "1.0"
ndk {
abiFilters "armeabi-v7a", "x86"
}
}
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
include "armeabi-v7a", "x86"
}
}
buildTypes {
release {
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
variant.outputs.each { output ->
// For each separate APK per architecture, set a unique version code as described here:
// http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
def versionCodes = ["armeabi-v7a":1, "x86":2]
def abi = output.getFilter(OutputFile.ABI)
if (abi != null) { // null for the universal-debug, universal-release variants
output.versionCodeOverride =
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
}
}
}
}
dependencies {
implementation project(':react-native-vector-icons')
implementation project(':react-native-firebase')
implementation project(':react-native-fcm')
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "com.android.support:appcompat-v7:27.0.+"
implementation "com.facebook.react:react-native:+" // From node_modules
implementation 'com.google.firebase:firebase-core:16.0.1'
implementation("com.google.firebase:firebase-messaging:17.0.0") {
force = true
}
}
task copyDownloadableDepsToLibs(type: Copy) {
from configurations.compile
into 'libs'
}
apply plugin: 'com.google.gms.google-services'
The build.gradle file:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.0'
classpath 'com.google.gms:google-services:3.2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenLocal()
jcenter()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
google()
}
}
MainApplication.java:
package com.watcher;
import android.app.Application;
import com.facebook.react.ReactApplication;
import com.oblador.vectoricons.VectorIconsPackage;
import io.invertase.firebase.RNFirebasePackage;
import com.evollu.react.fcm.FIRMessagingPackage;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage; // <-- Add this line
import java.util.Arrays;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
#Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
#Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new VectorIconsPackage(),
new RNFirebasePackage(),
new FIRMessagingPackage(),
new RNFirebaseMessagingPackage()
);
}
#Override
protected String getJSMainModuleName() {
return "index";
}
};
#Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
#Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.watcher">
<uses-permission android:name="android.permission.INTERNET" />
<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">
<activity
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" />
<service
android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
</application>
</manifest>
And the actual code that handles the notifications:
async checkPermission() {
const enabled = await firebase.messaging().hasPermission();
if (enabled) {
this.receiveToken();
} else {
this.requestPermission();
}
}
async receiveToken() {
let fcmToken = await AsyncStorage.getItem('fcmToken');
if (!fcmToken) {
fcmToken = await firebase.messaging().getToken();
if (fcmToken) {
await AsyncStorage.setItem('fcmToken', fcmToken);
}
}
return this.messageListener = firebase.messaging().onMessage(notif => {
try {
console.warn(JSON.stringify(notif));
} catch(e) {
console.warn("error trying to handle the message")
}
})
}
async requestPermission() {
try {
await firebase.messaging().requestPermission();
this.receiveToken();
} catch (error) {
console.warn('permission rejected');
}
}
componentDidMount() {
this.makeRemoteRequest();
this.checkPermission();
}
componentWillUnmount() {
this.messageListener();
}