Flutter fcm redirect issue - firebase

Hi in one of my flutter project, I am using firebase messaging. First a splash screen and second, the main page of the application. In second page, I implemented the firebase.configure method in the init state as follows. The _navigateToItemDetail method leads to an another page
#override
void initState() {
super.initState();
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
setState(() {
_newNotification = true;
});
},
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
_navigateToItemDetail(message);
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
_navigateToItemDetail(message);
},
);
and I cam calling the web service for this page after this. But the above method will launch after the webservice calls. So that will cause error in the page redirection. I just put a delay of 4 seconds in web service call, then it will works fine. Is there is any method to solve the issue ? async method available for firebase config ?

I think you need 'onBackgroundMessage'
firebaseMessaging.configure(
//...
onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler
//...
)
//...
static Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
//Do here something
}
as you can see, it only work on android

Related

Why onLaunch method of FCM is get called multiple times

Every time i click on push notification it will redirect to desired screen but if I goes to homescreen where i configure fcm it will redirect to that desired screen automatically instead to stay on homescreen
Plugin used - firebase_messaging: ^7.0.3
#override
void onInit() {
// TODO: implement onInit
super.onInit();
//forNotification();
firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
print("onMessage for type: ${message['notification_type']}");
//print("onMessage for title: ${message['aps']['title']}");
//Get.to(ServiceNotificationDetails(message['data']['notification_id']));
/*Get.to(ServiceNotificationDetails(index, serviceNotificationList));*/
},
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
print("onMessage for type: ${message['data']['notification_type']}");
moveTo(message, message['data']['notification_type']);
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
print("onMessage for type: ${message['data']['notification_type']}");
},
);
isFinalMethod.value = init.read("petowner");
print("IN OR NOT ");
tabController =
new TabController(length: isFinalMethod.value ? 3 : 2, vsync: this);
setImage();
}
void moveTo(Map<String, dynamic> message,String notification_type)async{
print("Notification type is $notification_type");
switch (notification_type){
case "1":
Get.offAll(ServiceNotificationDetails(message['data']['notification_id']));
break;
case "2":
Get.offAll(PetItemDetails(0,message['data']['project_id']));
break;
case "3":
Get.offAll(ServiceNotificationDetails(message['data']['notification_id']));
break;
}
}
forNotification()async{
if (!initialized) {
firebaseMessaging.requestNotificationPermissions();
firebaseMessaging.configure();
// For testing purposes print the Firebase Messaging token
String token = await firebaseMessaging.getToken();
print("FirebaseMessaging token: $token");
initialized = true;
}
}
Here's the code of fcm config and navigaton method.

Flutter: access SharedPreferences from onBackgroundMessage method of FirebaseMessaging

In my Flutter app I want to save data received from a Firebase Data Message to SharedPreferences.
I have the FirebaseMessaging object configured like this:
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) {
// this works fine
print("onMessage: ");
},
onLaunch: (Map<String, dynamic> data) {
print("onLaunch: ");
},
onResume: (Map<String, dynamic> data) {
print("onResume: ");
},
onBackgroundMessage: myBackgroundMessageHandler,
);
And this is the top-level myBackgroundMessageHandler method:
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) {
// This doesn't work
print("background message"); // this isn't even printed!
SharedPreferences.getInstance().then(...) // here I have to save some data
}
The problem is that myBackgroundMessageHandler seems not to be called at all.
However, the notification is received on the phone.
I also tryed to remove the notification field from the message and in that case myBackgroundMessageHandler is called but the notification doesn't arrive. Is there a way to both receive the notification and trigger the method?

Device didn't get message from FCM

I try to use FCM to send notification to my device but when i send it my device got nothing and i don't know did i do anything wrong ?
Plz tell me did i miss something ?
pubspec.yaml :
AndroidManifest.xml :
/android/build.gradle
/android/app/build.gradle
First of all, I think you mixed up screenshots.. but I'll give it a try:
build.gradle (App):
Add
dependencies {
implementation 'com.google.firebase:firebase-messaging:20.2.4'}
to the bottom.
on iOS devices:
You need to add the "Push Notification" Service to your Runnter Signing & Capabilities.
In your Code:
You need to initialise FCM
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
_showItemDialog(message);
},
onBackgroundMessage: myBackgroundMessageHandler,
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
_navigateToItemDetail(message);
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
_navigateToItemDetail(message);
},
);
For more information you can visit firebase_messaging installation walkthrough

How to handle fcm when app in in background and play sound on notification arrival in flutter

I want to play a sound when a notification arrives, but I am not able to play. If the app is opened the sound is played and is working fine. But when the app is killed I see the notification but the sound is not played.
Please help how to do it.
#override
void initState()
{
super.initState();
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print('on message $message');
String key = message["data"]["fcm_call_api"];
if (key == "approval") {}
if(Platform.isAndroid)``
{
_playSound();
}
},
onResume: (Map<String, dynamic> message) async {
},
onLaunch: (Map<String, dynamic> message) async {
_playSound();
},
);
_firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(sound: true, badge: true, alert: true));
_firebaseMessaging.onIosSettingsRegistered
.listen((IosNotificationSettings settings) {
});
_firebaseMessaging.getToken().then((String token) {
assert(token != null);
setState(() {
_homeScreenText = "Push Messaging token: $token";
});
});
}
void _playSound() {
AudioCache player = new AudioCache();
const alarmAudioPath = "notification_tone.mp3";
player.play(alarmAudioPath);
}
You did not specify on which platform you experience this problem, but overall background messages with the firebase messaging plugin is very limited right now, but there is a PR actively fixing this: https://github.com/flutter/plugins/pull/1900 (related issue: https://github.com/flutter/flutter/issues/22072)
Right now it is documented behavior that messages arriving in the background are only delivered once it is brought back into foreground (on android). See it's documentation at https://github.com/flutter/plugins/tree/master/packages/firebase_messaging#receiving-messages:

Flutter firebase push notification not routing to specific page

I am trying to navigate to a specific page when a notification is clicked. The onResume and onMessage callbacks are invoked when I click on the notification and I can see the message in the log screen. However, when I try to navigate to a specific page, I am not able to do that and there is no error message in the log too. P.S. When I used a Navigator key to access the state of the context(since in initState, the navigator cannot be used) I got an error saying no context to build. What is the mistake ??
I have tried Navigator.push, Calling a method and routing from within that method, used navigator key.
void initState() {
messaging.configure(
onMessage: (Map<String, dynamic> message) async {
print('onMessage: $message');
Navigator.of(context).push(
MaterialPageRoute<BuildContext>(builder: (_) => PageContent(value:1)));
},
onLaunch: (Map<String, dynamic> message) async {
print('onLaunch: $message');
Navigator.of(context).push(
MaterialPageRoute<BuildContext>(builder: (_) => PageContent(value:2)));
},
onResume: (Map<String, dynamic> message) async {
print('onResume:- This is the message $message');
Navigator.of(context).push(
MaterialPageRoute<BuildContext>(builder: (_) => MoviesList()));
},
);
I expect the code to be loaded when the notification is tapped and route to a new page( MoviesList or PageContent in my case). But only my home screen is visible.
Context is not available in init state
I came across this issue and get resolved using redux concepts
add a key in a global state like appNavigator
sample code for global app state (app_state.dart),
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:flutter/material.dart' hide Builder;
part 'app_state.g.dart';
abstract class AppState implements Built<AppState, AppStateBuilder> {
factory AppState([AppStateBuilder updates(AppStateBuilder builder)]) =
_$AppState;
AppState._();
static AppState initState() {
return new AppState((AppStateBuilder b) {
b
..appNavigator = new GlobalKey<NavigatorState>(debugLabel: 'debugLabel')
.. isLoggedIn = false
..isLoading = false;
});
}
// Never change this key through out the app lifecycle
GlobalKey<NavigatorState> get appNavigator;
// login state ***************************************************************************
bool get isLoggedIn;
// indicates loading state ***************************************************************************
bool get isLoading;
}
dispatch an action onMessage received from the notification like
onMessage: (Map<String, dynamic> message) async {
print('onMessage: $message');
store.dispatch(new RedirectUserOnNotification());
},
and in middleware route to a specific page with conditions validation as you needed.
void redirectuser(Store<AppState> store, RedirectUserOnNotification action,
NextDispatcher next) async {
store.state.appNavigator.currentState.pushNamed(someRouteName);
next(action);
}
Note: I have used build_value concepts in a model file

Resources