I am updating my Flutter app in order to receive Firebase Cloud Messaging messages.
I have followed all needed changes in the app and on Firebase console.
Now I am trying to send a test message from FCM to my android device, but it only receives a message when sent using the test message option with an specific token.
It doesn't receive a normal message to all devices.
This is the main.dart code I am using:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
},
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
},
);
_firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(
sound: true, badge: true, alert: true, provisional: false));
_firebaseMessaging.onIosSettingsRegistered
.listen((IosNotificationSettings settings) {
print("Settings registered: $settings");
});
_firebaseMessaging.getToken().then((String token) {
assert(token != null);
print("token firebase " + token);
});
runApp(new MaterialApp(
home: new MyApp(),
));
What am I doing wrong?
Make sure that all devices are subscribed to topic.
Related
I use firebase messaging for chats on a Flutter app. I added configuration part for firebase and notification, but when the user click on notification, the screen not opened and the FirebaseMessaging.onMessageOpenedApp method doesn't fired
I added firebase configuration on main method
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
await SessionManagement.init();
await SessionManagement.setUser();
DioUtil.getInstance();
if (!kIsWeb) {
channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
description: 'This channel is used for important notifications.',
importance: Importance.high,
);
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
await firebaseMessaging
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
}
runApp(AppProvider(child: MyApp()));
}
AndroidNotificationChannel channel;
FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance;
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
if(kDebugMode)
print('Handling a background message ${message.data}');
}
Then I added notification configuration on main screen.
#override
void initState() {
super.initState();
initFirebaseConfig();
}
void initFirebaseConfig() async {
requestPermission();
FirebaseMessaging.instance
.getInitialMessage()
.then((RemoteMessage message) {
if (message != null) {
_handleMessage(message);
}
});
FirebaseMessaging.onMessage.listen(showFlutterNotification);
FirebaseMessaging.onMessageOpenedApp.listen((event) {
print('Just received a notification when app is opened');
_handleMessage(event);
});
}
void showFlutterNotification(RemoteMessage message) {
print("heeeey onMessage" + message.toString());
RemoteNotification notification = message.notification;
AndroidNotification android = message.notification?.android;
if (notification != null && android != null && !kIsWeb) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
"New message from ${notification.title}",
notification.body,
NotificationDetails(
iOS: IOSNotificationDetails(subtitle: notification.title),
android: AndroidNotificationDetails(
channel.id,
channel.name,
channelDescription: channel.description,
icon: 'ic_notifications_icon',
),
),
);
}
}
void _handleMessage(RemoteMessage message) async {
print("heeeey onMessageOpenedApp" + message.toString());
NotificationModel notificationData =
NotificationModel.fromJson(message.data);
print(notificationData.data.toString());
if (notificationData.screen == "chats") {
Chat chat = Chat.fromJson(data: jsonDecode(notificationData.data));
print(chat.toString());
Navigator.of(context, rootNavigator: true)
.pushNamed(ChatScreen.routeName, arguments: chat);
// MyApp.navigatorKey.currentState.pushNamed('contact');
}
}
void requestPermission() async {
try {
NotificationSettings settings = await firebaseMessaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
print('User granted permission: ${settings.authorizationStatus}');
if (Platform.isIOS) {
await firebaseMessaging.setForegroundNotificationPresentationOptions(
alert: true, // Required to display a heads up notification
badge: true,
sound: true,
);
}
} catch (error) {
print('permission rejected');
}
}
After sending message I request firebase send message
static Future<void> sendNotification(
Chat chat, String deviceToken, String title) async {
final postUrl = 'https://fcm.googleapis.com/fcm/send';
NotificationModel notificationData = NotificationModel(
id: chat.id,
clickAction: "FLUTTER_NOTIFICATION_CLICK",
screen: "chats",
data: jsonEncode(chat.toJson()));
final data = {
"notification": {"body": chat.lastMessage.body, "title": title},
"priority": "high",
"data": notificationData.toJson(),
"to": deviceToken,
};
final headers = {
'content-type': 'application/json',
'Authorization':
'key=FIREBASE_KEY',
};
final response = await http.post(Uri.parse(postUrl),
body: json.encode(data),
encoding: Encoding.getByName('utf-8'),
headers: headers);
if (response.statusCode == 200) {
if (kDebugMode) print("true");
} else {
if (kDebugMode) print("heeeey!" + response.statusCode.toString());
}
}
I tried many code but it's still not working, could you please help me to find the issue
I am actually working with a e-commerce app and want to send notification to a delivery boy when order is placed from user app.
How can we identify the specific delivery boy app from backgroud (when app is exited).
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage
message) async {
await Firebase.initializeApp();
SharedPreferences _prefs = await SharedPreferences.getInstance();
print('A message just showed : ${message.messageId}');
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// <------------Local Notification Initilization-------------->
FirebaseMessaging.onBackgroundMessage(
_firebaseMessagingBackgroundHandler);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
runApp(MyApp());
}
Use http request to send notifications, and use topic parameter for specific user selection, check the code example that I've used in my case:
final String serverToken = 'YOUR_SERVER_TOKEN_HERE';
FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance;
Future<Map<String, dynamic>> sendAndRetrieveMessage(String typeOfNotification,
{String? sellerId, String? chatId, String? postId}) async {
NotificationSettings settings = await firebaseMessaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
String notification = getNotificationMessage(typeOfNotification);
notificationMsg.value = notification;
addToNotifications(sellerId!, notification, postId ?? "$userId", chatId ?? "$userId");
print('User granted permission: ${settings.authorizationStatus}');
String topic = '';
if (typeOfNotification == 'live') {
topic = "/topics/$userId";
} else if (typeOfNotification == 'post') {
topic = "/topics/$userId";
} else {
topic = "/topics/${sellerId}_personal";
}
await http.post(
Uri.parse('https://fcm.googleapis.com/fcm/send'),
headers: <String, String>{
'Content-Type': 'application/json',
'Authorization': 'key=$serverToken',
},
body: jsonEncode(
<String, dynamic>{
'notification': <String, dynamic>{
'body': "${userIsASeller.value ? shopName.value : userName.value} $notification",
'title': "Shopenlive",
},
'priority': 'high',
'data': <String, dynamic>{
'click_action': 'FLUTTER_NOTIFICATION_CLICK',
'id': '1',
'status': 'done',
'title': "Shopenlive",
'body': "${userIsASeller.value ? shopName.value : userName.value} $notification",
},
'to': topic,
},
),
);
final Completer<Map<String, dynamic>> completer = Completer<Map<String, dynamic>>();
/* firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
completer.complete(message);
},
); */
return completer.future;
}
// I am trying to decode the encoded title and message body received from the FCM notification before fire it up by the system.
_firebaseMessaging.configure(onMessage: (Map<String, dynamic> message) async {
// when app is running on foreground
},
onBackgroundMessage: myBackgroundMessageHandler,
onLaunch: (Map<String, dynamic> message) async {
//when app is terminated or not running
},
onResume: (Map<String, dynamic> message) async {
//when app is running in background
},
);
I want to enable/disable the notification service with help of a button when this button is enabled, the user receives the notification, and when it's disabled he won't receive any notifications.
import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
class FirebaseNotifications {
FirebaseMessaging _firebaseMessaging;
void setUpFirebase() {
_firebaseMessaging = FirebaseMessaging();
firebaseCloudMessaging_Listeners();
}
void firebaseCloudMessaging_Listeners() {
if (Platform.isIOS) iOS_Permission();
_firebaseMessaging.getToken().then((token) {
print(token);
});
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print('on message $message');
},
onResume: (Map<String, dynamic> message) async {
print('on resume $message');
},
onLaunch: (Map<String, dynamic> message) async {
print('on launch $message');
},
);
}
void iOS_Permission() {
_firebaseMessaging.requestNotificationPermissions(
IosNotificationSettings(sound: true, badge: true, alert: true));
_firebaseMessaging.onIosSettingsRegistered
.listen((IosNotificationSettings settings) {
print("Settings registered: $settings");
});
}
}
what you should do is that when implementing the notifications subscribe the user to a topic with
FirebaseMessaging.instance.subscribeToTopic ('news');
If this user wants to deactivate notifications, you only unsubscribe from the topic with
FirebaseMessaging.instance.unsubscribeFromTopic ('news');
Obviously when you send the notifications from the backend or console, you must specify this topic "news" or the name that you decide to put it
I am using flutter firebase cloud messaging plug in and it is working fine. I want to receive the message only when user is logged in . I am receiving notification even after user is logged off.
I have following code . which runs even after user is logged off. How to stop following code when user is logged off.
_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);
},
);
just check if the user is logged in your app or not by checking the value of your shared preferences as soon as you receive the push notification,
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
if (myPref.get('isLoggedin')){// here you check if user is logged in or not
_showItemDialog(message);
}
else
//do nothing
},
FirebaseAuth.instance.currentUser().then((firebaseUser){
if(firebaseUser == null) {
//signed out
}
else{
//signed in
showMessage();
} });