flutter FCM subscribe to a topic doesn't seem to work - flutter

I implemented FCM successfully. When i send a message from firebase console it comes to the emulator as well. But when i subscribe to a topic it doesn't filter any of the messages. It doesn't matter what i write to channel on firebase console, it comes anyway. Here is my main method.
Here is my main method:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
// FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
await FirebaseMessaging.instance
.subscribeToTopic('Herkes');
SharedPreferences.getInstance().then((prefs) {
runApp(
ChangeNotifierProvider<ThemeNotifier>(
create: (_) => ThemeNotifier(prefs.getString('theme')),
child: MyApp(),
),
);
});
}
And my console logs after any message come:
W/FirebaseMessaging( 4985): Notification Channel requested (Public2) has not been created by the app. Manifest configuration, or default, value will be used.
W/FirebaseMessaging( 4985): Notification Channel set in AndroidManifest.xml has not been created by the app. Default value will be used.

As in the official docs, you need to add the following metadata element in your AndroidManifest.xml within the application component:
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="#string/default_notification_channel_id"/>

Related

Flutter/Firebase: Need to provide options, when not being deployed to hosting via source

I have an app that runs fine on Android, but when I try to start it for Flutter Web, I get
Uncaught (in promise) Error: [core/no-options] Firebase: Need to provide options, when not being deployed to hosting via source.. The stack trace doesn't go far enough back to point to a spot in my code.
void main() async {
await WidgetsFlutterBinding.ensureInitialized(); // I've tried moving this after
await Firebase.initializeApp(
name: "---",
options: FirebaseOptions(
apiKey: DefaultFirebaseOptions.currentPlatform.apiKey,
appId: DefaultFirebaseOptions.currentPlatform.appId,
messagingSenderId: DefaultFirebaseOptions.currentPlatform.messagingSenderId,
projectId: DefaultFirebaseOptions.currentPlatform.projectId),
);
runApp(const MyApp());
}
If I remove initializeApp(), the app starts to load, and I get a different ear for Firebase not being configured.
if I wrap delay it, like so, it delays the error for 5 seconds, so it's definitely this line
void main() async {
await WidgetsFlutterBinding.ensureInitialized();
await Future.delayed(Duration(seconds: 5), () async {
await Firebase.initializeApp(
name: "---",
options: FirebaseOptions(
apiKey: DefaultFirebaseOptions.currentPlatform.apiKey,
appId: DefaultFirebaseOptions.currentPlatform.appId,
messagingSenderId: DefaultFirebaseOptions.currentPlatform.messagingSenderId,
projectId: DefaultFirebaseOptions.currentPlatform.projectId),
);
});
await Future.delayed(Duration(seconds: 5), () async {
runApp(const MyApp());
});
}
The solution for me was to remove the name Attribute. Apparently it's a recurring bug in the package.
https://github.com/firebase/flutterfire/issues/10228
I just ran the example in FlutterFire - FirebaseCore/Example. This
works just fine!
I narrowed down the issue to the following: Our application works just
fine when I remove the name parameter from the initialization call.
However when I add this I get the error message from above.
Looks to me like somewhere in firebase_auth_web.dart it defaults to
the default app.

Firebase crashlytics is not reporting anything on Flutter

I've initialized and configured Firebase for my Flutter project using this documentation and the instructions given by the Firebase Console. After that, I followed this crashlytics documentation for adding crashlytics to my app. But no matter what I've tried, I couldn't see any reports on the Firebase console. Still seeing this;
My main function looks like this:
Future main() async {
runZonedGuarded(
() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
runApp(const App());
},
(error, stack) async {
await FirebaseCrashlytics.instance.recordError(error, stack);
},
);
}
I've tried to;
crash my app using FirebaseCrashlytics.instance.crash()
throw an exception and record it by the onError callback of the runZonedGuarded
manually record an exception using FirebaseCrashlytics.recordError(error, stack)
setting fatal: true or using FirebaseCrashlytics.instance.recordFlutterFatalError
Is there something that I'm missing? I'm really stuck at this point.

How to handle click on push-notification when application is in foreground?

I use the Firebase Cloud Messaging (FCM) in my Flutter project. The following packages:
firebase_messaging: ^8.0.0-dev.15
flutter_local_notifications: ^4.0.1+2
I know that I can handle click on push-notification when app is in background in the following way:
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
//TODO
});
and it works fine, but how to handle click on push-notification when application is in foreground? Can't find in the documentation as well. Could you please help me. Thanks in advance.
you can set the callback function on initializing
await flutterLocalNotificationsPlugin.initialize(
const InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
),
onSelectNotification: handleClickNotification,
);
handleClickNotification(String? payload) {
//your code
}
Use this dependency when the app is in foreground- https://pub.dev/packages/flutter_local_notifications
Edit
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
//TODO
});
You are already using this code for when the app is in background. See that you are using onMessageOpenedApp. For firing the message when in foreground you can use onMessage. Example-
FirebaseMessaging.onMessage.listen((message) {
LocalNotificationService.display(message);
});

Flutter Local Notifications doesn't execute code with app terminated

I have an app that schedules alarms, which trigger flutter local notifications. When pressing one of the buttons on these notifications, the database gets updated to reflect that you've turned off the alarm.
However, when the app is terminated/closed down, it seems as if no code gets executed and the database doesn't get updated.
The notification does get triggered, it's when the user presses a button inside of it that no code gets executed. Looks something like this
I'd like to know if what I'm trying is even possible, because at this point I'm not sure.
The notifications are created using the zonedSchedule from the flutter local notifications plugin.
The app does not get opened when pressing one of the buttons in the notification.
The code is as follows:
class LocalNoticationsService {
LocalNoticationsService(
this._notificationsPlugin,
);
final FlutterLocalNotificationsPlugin _notificationsPlugin;
Future<void> init() async {
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings(
'img/path',// path to notification icon
);
final DarwinInitializationSettings initializationSettingsIOS = DarwinInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,
defaultPresentAlert: true,
defaultPresentSound: true,
notificationCategories: [
DarwinNotificationCategory(
'category',
options: {
DarwinNotificationCategoryOption.allowAnnouncement,
},
actions: [
DarwinNotificationAction.plain(
'snoozeAction',
'snooze',
),
DarwinNotificationAction.plain(
'confirmAction',
'confirm',
options: {
DarwinNotificationActionOption.authenticationRequired,
},
),
],
),
],
);
final InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
await _notificationsPlugin.initialize(
initializationSettings,
onSelectNotification: _onSelectedNotification,
onSelectNotificationAction: onSelectNotificationAction,
);
final notificationOnLaunchDetails = await _notificationsPlugin.getNotificationAppLaunchDetails();
if (notificationOnLaunchDetails?.didNotificationLaunchApp ?? false) {
_onSelectedNotification(notificationOnLaunchDetails!.payload);
}
}
void _onSelectedNotification(String? payload) {
// Not relevant to this problem
}
Future<bool> _confirmAlarm(AlarmPayLoad alarmPayload) async {
// Update database
}
}
// Top level function
Future<void> onSelectNotificationAction(NotificationActionDetails details) async {
await Firebase.initializeApp();
final localNotificationsService = LocalNoticationsService(
FlutterLocalNotificationsPlugin()
);
await localNotificationsService.init();
final alarmPayload = AlarmPayLoad.fromJson(details.payload);
await localNotificationsService._confirmAlarm(alarmPayload)
}
Due to this all running in the background, I've been unable to find a way to log things. I've tried using the http package to send post request to a webhook with some data, but these do not seem to trigger when the app is terminated, but do work when in the app is in the foreground or in the background(not closed).
Any post or videos I've found online about flutter local notifications don't seem to cover this problem or are using firebase push notifications and the associated package for background handling.
I'd be very interested to hear any feedback on what might be going wrong or what might be the solution and how handling background notifications works. If you need additional information on the code, feel free to ask.
If you want to run it on background, follow the link here.

How to add android notification channel id for flutter app to fix notification while app is on background

In my flutter app the function onResume and onLunch not working on android platform, while they work fine on IOS,
i receive the following message on console instead of printed strings in those functions:
"W/FirebaseMessaging(24847): Missing Default Notification Channel metadata in AndroidManifest. Default value will be used."
onMessage function works fine, the problem is when the app is in background
my guess is that it has something to do with android notification channel id which should be added in android manifest
when i add that to manifest with adding the following code to AndroidManifest the message change to :
(I added a strings.xml file in values and defined "default_notification_channel_id" there.)
"Notification Channel set in AndroidManifest.xml has not been created by the app. Default value will be used."
<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="#string/default_notification_channel_id"/>
in my console i should receive onResume and onLunch strings which i printed , but instead i receive following messages :
"W/FirebaseMessaging(24847): Missing Default Notification Channel metadata in AndroidManifest. Default value will be used."
"Notification Channel set in AndroidManifest.xml has not been created by the app. Default value will be used."
<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="#string/default_notification_channel_id"/>
You should create a notification channel first, the plugin: flutter_local_notifications can create and remove notification channels.
First, initialize the plugin:
Future<void> initializeLocalNotifications() async {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
// app_icon needs to be a added as a drawable resource to the
// Android head project
var initializationSettingsAndroid = AndroidInitializationSettings('app_icon');
var initializationSettingsIOS = IOSInitializationSettings(
onDidReceiveLocalNotification: onDidReceiveLocalNotification);
var initializationSettings = InitializationSettings(
initializationSettingsAndroid, initializationSettingsIOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: selectNotification);
}
Second, create notification channel using this plugin:
Future<void> _createNotificationChannel(String id, String name,
String description) async {
final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
var androidNotificationChannel = AndroidNotificationChannel(
id,
name,
description,
);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(androidNotificationChannel);
}
Now you have two options:
Create a channel with the default id you already defined in AndroidManifest.xml
Choose your own channel ids and send each notification to a specific channel by embedding the channel id into your FCM notification message. To do so, add channel_id tag to your notification under notification tag, under android tag.
Here is a sample notification message from Firebase Functions with custom notification channel id:
'notification': {
'title': your_title,
'body': your_body,
},
'android': {
'notification': {
'channel_id': your_channel_id,
},
},
have you created default_notification_channel_id ?
"W/FirebaseMessaging(24847): Missing Default Notification Channel metadata in AndroidManifest. Default value will be used."
You have this warning when you don't set the channel_id in the payload of the notification