Open certain page on push notification using firebase cloud messaging on flutter
I've manage to push a notification to my flutter app using firebase cloud messaging. what I'm trying to do right now is that, once i click the notification, it will directly to a certain page that the app have. How do i redirect the notification to a certain page? thank you
dart flutter
add a comment |
I've manage to push a notification to my flutter app using firebase cloud messaging. what I'm trying to do right now is that, once i click the notification, it will directly to a certain page that the app have. How do i redirect the notification to a certain page? thank you
dart flutter
Use a GlobalKey to get a reference to a widget that has a Navigator in it's context and then use this reference to navigate to a specific route.
– Günter Zöchbauer
Nov 21 '18 at 9:35
@GünterZöchbauer do you have any example or reference on how to do it?
– ali
Nov 22 '18 at 1:21
add a comment |
I've manage to push a notification to my flutter app using firebase cloud messaging. what I'm trying to do right now is that, once i click the notification, it will directly to a certain page that the app have. How do i redirect the notification to a certain page? thank you
dart flutter
I've manage to push a notification to my flutter app using firebase cloud messaging. what I'm trying to do right now is that, once i click the notification, it will directly to a certain page that the app have. How do i redirect the notification to a certain page? thank you
dart flutter
dart flutter
asked Nov 21 '18 at 9:32
aliali
599
599
Use a GlobalKey to get a reference to a widget that has a Navigator in it's context and then use this reference to navigate to a specific route.
– Günter Zöchbauer
Nov 21 '18 at 9:35
@GünterZöchbauer do you have any example or reference on how to do it?
– ali
Nov 22 '18 at 1:21
add a comment |
Use a GlobalKey to get a reference to a widget that has a Navigator in it's context and then use this reference to navigate to a specific route.
– Günter Zöchbauer
Nov 21 '18 at 9:35
@GünterZöchbauer do you have any example or reference on how to do it?
– ali
Nov 22 '18 at 1:21
Use a GlobalKey to get a reference to a widget that has a Navigator in it's context and then use this reference to navigate to a specific route.
– Günter Zöchbauer
Nov 21 '18 at 9:35
Use a GlobalKey to get a reference to a widget that has a Navigator in it's context and then use this reference to navigate to a specific route.
– Günter Zöchbauer
Nov 21 '18 at 9:35
@GünterZöchbauer do you have any example or reference on how to do it?
– ali
Nov 22 '18 at 1:21
@GünterZöchbauer do you have any example or reference on how to do it?
– ali
Nov 22 '18 at 1:21
add a comment |
1 Answer
1
active
oldest
votes
I have something like this, in my FCM class:
static StreamController<Map<String, dynamic>> _onMessageStreamController =
StreamController.broadcast();
static StreamController<Map<String, dynamic>> _streamController =
StreamController.broadcast();
static final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
static final Stream<Map<String, dynamic>> onFcmMessage =
_streamController.stream;
static setupFCMListeners() {
print("Registered FCM Listeners");
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
_onMessageStreamController.add(message);
},
onLaunch: (Map<String, dynamic> message) async {
_streamController.add(message);
},
onResume: (Map<String, dynamic> message) async {
_streamController.add(message);
},
);
}
static Widget handlePath(Map<String, dynamic> dataMap) {
var path = dataMap["route"];
var id = dataMap["id"];
return handlePathByRoute(path, id);
}
static Widget handlePathByRoute(String route, String routeId) {
switch (route) {
case "user":
return Profile(guid: routeId);
case "event":
return EventInfo(eventId: routeId);
case "messaging":
return MessagingView(guid: routeId);
default:
return null;
}
}
My main.dart
subscribes to onFcmMessage stream, but you don't need streams to do all this. Also, you need some code to handle stream failure and closure.
But when the app comes to foreground it gets the message on either onMessage
callback or the onLaunch
or onResume
callback. Check their differences on the FCM flutter pub docs.
The methods handlePath
and handlePathByRoute
are methods that usually my main.dart or other classes listening to notifications call to get the path to route to, but you can simply call them directly by replacing the stream code here like:
static setupFCMListeners() {
print("Registered FCM Listeners");
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("Message: $message"); // Not handling path since on notification in app it can be weird to open a new page randomly.
},
onLaunch: (Map<String, dynamic> message) async {
handlePath(message);
},
onResume: (Map<String, dynamic> message) async {
handlePath(message);
},
);
}
This honestly may not even be the best or even a good approach but due to lack of documentation, this is what I'm working with for now. I'd love to try Günter Zöchbauer's approach and save some object creation if possible!
Hope this is helpful! :)
EDIT: Profile
, EventInfo
and MessagingView
are three classes that extend StatefulWidget
, sorry if that wasn't clear.
You can also try using named routes, they make it easier like api routes and avoid a lot of imports and have a central router, but AFAIK they lacked transition configurations.
which one should be on the main.dart? And should i make a new file for the FCM class?
– ali
Nov 22 '18 at 1:22
There's no rules for this. Just handle the callbacks onMessage, onLaunch and onResume wherever you like. I just gave you an example of what I do to handle data notification payloads. Also make sure you pass in the FLUTTER_NOTIFICATION_CLICK argument from your backend. Creating a FCM class maybe helpful if you want to access FCM messages from multiple classes not just main.dart. That's been the case for me and hence I use streams to subscribe on need.
– ishaan
Nov 22 '18 at 13:13
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53408967%2fopen-certain-page-on-push-notification-using-firebase-cloud-messaging-on-flutter%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I have something like this, in my FCM class:
static StreamController<Map<String, dynamic>> _onMessageStreamController =
StreamController.broadcast();
static StreamController<Map<String, dynamic>> _streamController =
StreamController.broadcast();
static final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
static final Stream<Map<String, dynamic>> onFcmMessage =
_streamController.stream;
static setupFCMListeners() {
print("Registered FCM Listeners");
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
_onMessageStreamController.add(message);
},
onLaunch: (Map<String, dynamic> message) async {
_streamController.add(message);
},
onResume: (Map<String, dynamic> message) async {
_streamController.add(message);
},
);
}
static Widget handlePath(Map<String, dynamic> dataMap) {
var path = dataMap["route"];
var id = dataMap["id"];
return handlePathByRoute(path, id);
}
static Widget handlePathByRoute(String route, String routeId) {
switch (route) {
case "user":
return Profile(guid: routeId);
case "event":
return EventInfo(eventId: routeId);
case "messaging":
return MessagingView(guid: routeId);
default:
return null;
}
}
My main.dart
subscribes to onFcmMessage stream, but you don't need streams to do all this. Also, you need some code to handle stream failure and closure.
But when the app comes to foreground it gets the message on either onMessage
callback or the onLaunch
or onResume
callback. Check their differences on the FCM flutter pub docs.
The methods handlePath
and handlePathByRoute
are methods that usually my main.dart or other classes listening to notifications call to get the path to route to, but you can simply call them directly by replacing the stream code here like:
static setupFCMListeners() {
print("Registered FCM Listeners");
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("Message: $message"); // Not handling path since on notification in app it can be weird to open a new page randomly.
},
onLaunch: (Map<String, dynamic> message) async {
handlePath(message);
},
onResume: (Map<String, dynamic> message) async {
handlePath(message);
},
);
}
This honestly may not even be the best or even a good approach but due to lack of documentation, this is what I'm working with for now. I'd love to try Günter Zöchbauer's approach and save some object creation if possible!
Hope this is helpful! :)
EDIT: Profile
, EventInfo
and MessagingView
are three classes that extend StatefulWidget
, sorry if that wasn't clear.
You can also try using named routes, they make it easier like api routes and avoid a lot of imports and have a central router, but AFAIK they lacked transition configurations.
which one should be on the main.dart? And should i make a new file for the FCM class?
– ali
Nov 22 '18 at 1:22
There's no rules for this. Just handle the callbacks onMessage, onLaunch and onResume wherever you like. I just gave you an example of what I do to handle data notification payloads. Also make sure you pass in the FLUTTER_NOTIFICATION_CLICK argument from your backend. Creating a FCM class maybe helpful if you want to access FCM messages from multiple classes not just main.dart. That's been the case for me and hence I use streams to subscribe on need.
– ishaan
Nov 22 '18 at 13:13
add a comment |
I have something like this, in my FCM class:
static StreamController<Map<String, dynamic>> _onMessageStreamController =
StreamController.broadcast();
static StreamController<Map<String, dynamic>> _streamController =
StreamController.broadcast();
static final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
static final Stream<Map<String, dynamic>> onFcmMessage =
_streamController.stream;
static setupFCMListeners() {
print("Registered FCM Listeners");
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
_onMessageStreamController.add(message);
},
onLaunch: (Map<String, dynamic> message) async {
_streamController.add(message);
},
onResume: (Map<String, dynamic> message) async {
_streamController.add(message);
},
);
}
static Widget handlePath(Map<String, dynamic> dataMap) {
var path = dataMap["route"];
var id = dataMap["id"];
return handlePathByRoute(path, id);
}
static Widget handlePathByRoute(String route, String routeId) {
switch (route) {
case "user":
return Profile(guid: routeId);
case "event":
return EventInfo(eventId: routeId);
case "messaging":
return MessagingView(guid: routeId);
default:
return null;
}
}
My main.dart
subscribes to onFcmMessage stream, but you don't need streams to do all this. Also, you need some code to handle stream failure and closure.
But when the app comes to foreground it gets the message on either onMessage
callback or the onLaunch
or onResume
callback. Check their differences on the FCM flutter pub docs.
The methods handlePath
and handlePathByRoute
are methods that usually my main.dart or other classes listening to notifications call to get the path to route to, but you can simply call them directly by replacing the stream code here like:
static setupFCMListeners() {
print("Registered FCM Listeners");
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("Message: $message"); // Not handling path since on notification in app it can be weird to open a new page randomly.
},
onLaunch: (Map<String, dynamic> message) async {
handlePath(message);
},
onResume: (Map<String, dynamic> message) async {
handlePath(message);
},
);
}
This honestly may not even be the best or even a good approach but due to lack of documentation, this is what I'm working with for now. I'd love to try Günter Zöchbauer's approach and save some object creation if possible!
Hope this is helpful! :)
EDIT: Profile
, EventInfo
and MessagingView
are three classes that extend StatefulWidget
, sorry if that wasn't clear.
You can also try using named routes, they make it easier like api routes and avoid a lot of imports and have a central router, but AFAIK they lacked transition configurations.
which one should be on the main.dart? And should i make a new file for the FCM class?
– ali
Nov 22 '18 at 1:22
There's no rules for this. Just handle the callbacks onMessage, onLaunch and onResume wherever you like. I just gave you an example of what I do to handle data notification payloads. Also make sure you pass in the FLUTTER_NOTIFICATION_CLICK argument from your backend. Creating a FCM class maybe helpful if you want to access FCM messages from multiple classes not just main.dart. That's been the case for me and hence I use streams to subscribe on need.
– ishaan
Nov 22 '18 at 13:13
add a comment |
I have something like this, in my FCM class:
static StreamController<Map<String, dynamic>> _onMessageStreamController =
StreamController.broadcast();
static StreamController<Map<String, dynamic>> _streamController =
StreamController.broadcast();
static final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
static final Stream<Map<String, dynamic>> onFcmMessage =
_streamController.stream;
static setupFCMListeners() {
print("Registered FCM Listeners");
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
_onMessageStreamController.add(message);
},
onLaunch: (Map<String, dynamic> message) async {
_streamController.add(message);
},
onResume: (Map<String, dynamic> message) async {
_streamController.add(message);
},
);
}
static Widget handlePath(Map<String, dynamic> dataMap) {
var path = dataMap["route"];
var id = dataMap["id"];
return handlePathByRoute(path, id);
}
static Widget handlePathByRoute(String route, String routeId) {
switch (route) {
case "user":
return Profile(guid: routeId);
case "event":
return EventInfo(eventId: routeId);
case "messaging":
return MessagingView(guid: routeId);
default:
return null;
}
}
My main.dart
subscribes to onFcmMessage stream, but you don't need streams to do all this. Also, you need some code to handle stream failure and closure.
But when the app comes to foreground it gets the message on either onMessage
callback or the onLaunch
or onResume
callback. Check their differences on the FCM flutter pub docs.
The methods handlePath
and handlePathByRoute
are methods that usually my main.dart or other classes listening to notifications call to get the path to route to, but you can simply call them directly by replacing the stream code here like:
static setupFCMListeners() {
print("Registered FCM Listeners");
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("Message: $message"); // Not handling path since on notification in app it can be weird to open a new page randomly.
},
onLaunch: (Map<String, dynamic> message) async {
handlePath(message);
},
onResume: (Map<String, dynamic> message) async {
handlePath(message);
},
);
}
This honestly may not even be the best or even a good approach but due to lack of documentation, this is what I'm working with for now. I'd love to try Günter Zöchbauer's approach and save some object creation if possible!
Hope this is helpful! :)
EDIT: Profile
, EventInfo
and MessagingView
are three classes that extend StatefulWidget
, sorry if that wasn't clear.
You can also try using named routes, they make it easier like api routes and avoid a lot of imports and have a central router, but AFAIK they lacked transition configurations.
I have something like this, in my FCM class:
static StreamController<Map<String, dynamic>> _onMessageStreamController =
StreamController.broadcast();
static StreamController<Map<String, dynamic>> _streamController =
StreamController.broadcast();
static final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
static final Stream<Map<String, dynamic>> onFcmMessage =
_streamController.stream;
static setupFCMListeners() {
print("Registered FCM Listeners");
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
_onMessageStreamController.add(message);
},
onLaunch: (Map<String, dynamic> message) async {
_streamController.add(message);
},
onResume: (Map<String, dynamic> message) async {
_streamController.add(message);
},
);
}
static Widget handlePath(Map<String, dynamic> dataMap) {
var path = dataMap["route"];
var id = dataMap["id"];
return handlePathByRoute(path, id);
}
static Widget handlePathByRoute(String route, String routeId) {
switch (route) {
case "user":
return Profile(guid: routeId);
case "event":
return EventInfo(eventId: routeId);
case "messaging":
return MessagingView(guid: routeId);
default:
return null;
}
}
My main.dart
subscribes to onFcmMessage stream, but you don't need streams to do all this. Also, you need some code to handle stream failure and closure.
But when the app comes to foreground it gets the message on either onMessage
callback or the onLaunch
or onResume
callback. Check their differences on the FCM flutter pub docs.
The methods handlePath
and handlePathByRoute
are methods that usually my main.dart or other classes listening to notifications call to get the path to route to, but you can simply call them directly by replacing the stream code here like:
static setupFCMListeners() {
print("Registered FCM Listeners");
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("Message: $message"); // Not handling path since on notification in app it can be weird to open a new page randomly.
},
onLaunch: (Map<String, dynamic> message) async {
handlePath(message);
},
onResume: (Map<String, dynamic> message) async {
handlePath(message);
},
);
}
This honestly may not even be the best or even a good approach but due to lack of documentation, this is what I'm working with for now. I'd love to try Günter Zöchbauer's approach and save some object creation if possible!
Hope this is helpful! :)
EDIT: Profile
, EventInfo
and MessagingView
are three classes that extend StatefulWidget
, sorry if that wasn't clear.
You can also try using named routes, they make it easier like api routes and avoid a lot of imports and have a central router, but AFAIK they lacked transition configurations.
answered Nov 21 '18 at 9:53
ishaanishaan
830921
830921
which one should be on the main.dart? And should i make a new file for the FCM class?
– ali
Nov 22 '18 at 1:22
There's no rules for this. Just handle the callbacks onMessage, onLaunch and onResume wherever you like. I just gave you an example of what I do to handle data notification payloads. Also make sure you pass in the FLUTTER_NOTIFICATION_CLICK argument from your backend. Creating a FCM class maybe helpful if you want to access FCM messages from multiple classes not just main.dart. That's been the case for me and hence I use streams to subscribe on need.
– ishaan
Nov 22 '18 at 13:13
add a comment |
which one should be on the main.dart? And should i make a new file for the FCM class?
– ali
Nov 22 '18 at 1:22
There's no rules for this. Just handle the callbacks onMessage, onLaunch and onResume wherever you like. I just gave you an example of what I do to handle data notification payloads. Also make sure you pass in the FLUTTER_NOTIFICATION_CLICK argument from your backend. Creating a FCM class maybe helpful if you want to access FCM messages from multiple classes not just main.dart. That's been the case for me and hence I use streams to subscribe on need.
– ishaan
Nov 22 '18 at 13:13
which one should be on the main.dart? And should i make a new file for the FCM class?
– ali
Nov 22 '18 at 1:22
which one should be on the main.dart? And should i make a new file for the FCM class?
– ali
Nov 22 '18 at 1:22
There's no rules for this. Just handle the callbacks onMessage, onLaunch and onResume wherever you like. I just gave you an example of what I do to handle data notification payloads. Also make sure you pass in the FLUTTER_NOTIFICATION_CLICK argument from your backend. Creating a FCM class maybe helpful if you want to access FCM messages from multiple classes not just main.dart. That's been the case for me and hence I use streams to subscribe on need.
– ishaan
Nov 22 '18 at 13:13
There's no rules for this. Just handle the callbacks onMessage, onLaunch and onResume wherever you like. I just gave you an example of what I do to handle data notification payloads. Also make sure you pass in the FLUTTER_NOTIFICATION_CLICK argument from your backend. Creating a FCM class maybe helpful if you want to access FCM messages from multiple classes not just main.dart. That's been the case for me and hence I use streams to subscribe on need.
– ishaan
Nov 22 '18 at 13:13
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53408967%2fopen-certain-page-on-push-notification-using-firebase-cloud-messaging-on-flutter%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Use a GlobalKey to get a reference to a widget that has a Navigator in it's context and then use this reference to navigate to a specific route.
– Günter Zöchbauer
Nov 21 '18 at 9:35
@GünterZöchbauer do you have any example or reference on how to do it?
– ali
Nov 22 '18 at 1:21