Firebase packages - Error: Couldn't resolve the package | Flutter - flutter

I divide the hms and gms services in my project, and I also created a local packages that is a collection of my own helper classes for push notification service
The dependencies of local package for gms devices include firebase_core and firebase_messaging. Dart analytics doesn't shows the problem "Undefinded" which appear when dependencies are not loaded by pub get or doesn`t exist in pubspec.yaml. But when i started debug build, it have exceptions
pubspec.yaml:
name: push_service
description: A new Flutter package project.
version: 0.0.1
homepage:
publish_to: none
environment:
sdk: ">=2.17.1 <3.0.0"
flutter: ">=1.17.0"
dependencies:
flutter:
sdk: flutter
push_service_interface:
path: ../../interface/push_service_interface
firebase_analytics: ^9.1.4
firebase_core: ^1.12.0
firebase_messaging: ^11.2.6
flutter_local_notifications: ^9.2.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
flutter:
The part of my code:
class GmsService implements IService {
#override
Future<void> init() async {
await Firebase.initializeApp();
if (Platform.isIOS) {
await Firebase.initializeApp(options: _firebaseOptions);
} else {
await Firebase.initializeApp();
}
FirebaseMessaging fcm = FirebaseMessaging.instance;
///Request permissions for Ios
await fcm.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
}
#override
Future<String?> getToken() async {
return await FirebaseMessaging.instance.getToken();
}
#override
Future<void> backgroundHandler() async {
FirebaseMessaging.onBackgroundMessage((message) async {
if (Platform.isIOS) {
await Firebase.initializeApp(options: _firebaseOptions);
} else {
await Firebase.initializeApp();
}
log("[Firebase] Handling a background message: ${message.messageId}");
});
}
#override
Future<void> onTapWhenAppClosed({required Function() onTap}) async {
FirebaseMessaging.instance.getInitialMessage().then((message) {
if (message != null) {
onTap;
}
});
}
#override
Future<void> onTapWhenAppFon({required Function() onTap}) async {
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
onTap;
});
}
#override
Future<void> listener<T>({T? plugin}) async {
plugin as FlutterLocalNotificationsPlugin;
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification? notification = message.notification;
// AndroidNotification? android = message.notification?.android;
if (notification != null) {
plugin.show(
notification.hashCode,
notification.title,
notification.body,
const NotificationDetails(
iOS: IOSNotificationDetails(),
android: AndroidNotificationDetails(
'default_notification_channel',
'Notifications',
channelDescription: 'This channel is used for notifications.',
icon: '#drawable/res_notification_logo',
color: Colors.orange,
),
),
);
}
});
}
}
const FirebaseOptions _firebaseOptions = FirebaseOptions(
apiKey: "AIzaSyDlDrc6NbcGVR4rr8DTfV82dAk_vD3Jpi0",
appId: "1:150088765423:ios:23edb87f9ecb47a756301a",
messagingSenderId: "150088765423",
projectId: "android-foxfit-push",
);
And the build output:
I`m really tired to find the solution of this problem, anybody help me pls

Related

Flutter Firebase background push in terminated state

Flutter Firebase background push in terminated state has not been handled.
My env and deps :
Android 11, Nokia G21
environment:
sdk: ">=2.14.0 <3.0.0"
flutter: "^3.3.6"
firebase_messaging: ^14.0.3
firebase_core: ^2.1.1
firebase_crashlytics: ^3.0.3
main.dart:
late AndroidNotificationChannel channel;
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
bool isFlutterLocalNotificationsInitialized = false;
#pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
await setupFlutterNotifications();
showFlutterNotification(message);
Logger().i("Handling a background message: ${message.messageId}");
}
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await SharedPreferences.getInstance();
await FlutterConfig.loadEnvVariables();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
await setupFlutterNotifications();
FirebaseMessaging.onMessage.listen((event) {
Logger().e('$CLASS_TAG onMessage ${event.data.toString()}');
showFlutterNotification(event);
});
runZonedGuarded(
() => runApp(const ErkcRequestApp()),
(Object object, StackTrace stackTrace) => dev.log(
object.toString(),
error: object,
stackTrace: stackTrace,
),
);
}
Used this example, also tried this, but still get error.
Error from Logcat (app in terminated state):

Navigate to another screen when I click on Firebase push notification either in foreground or background in Flutter

I use Firebase messaging in my Flutter app , I want to navigate to another screen when I click on the notification even my app is in foreground or background , I used many functions and it doesn't trigger the click event and I can't find anything can solve my problem .
When I click on the notification when app is in foreground or background , nothing happened because it navigate to the same page .
And when I click on the notification when app is terminated , it opens on Splash screen and go to the home not the screen that I want .
I added this intent-filter in my Manifest
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
And I added this to the Json object
"click_action": "FLUTTER_NOTIFICATION_CLICK",
And here is how can I get background FCM in the main.dart
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance', // id
'High Importance Notifications', // title
importance: Importance.high,
playSound: true);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
SessionManager sessionManager = SessionManager();
await Firebase.initializeApp();
//final sound = 'sound.mp3';
print('A bg message just showed up : ${message.messageId}');
final android = AndroidInitializationSettings('#mipmap/ic_launcher');
final ios = IOSInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,);
final settings = InitializationSettings(android: android,iOS: ios);
flutterLocalNotificationsPlugin.initialize(settings,);
if(message.data['title'].toString().toLowerCase()=="new request") {
sessionManager.getBadge().then((badge) {
if (badge != null) {
int x = badge + 1;
sessionManager.saveBadge(x);
print("notification number is " + x.toString());
}
else {
sessionManager.saveBadge(1);
}
});
}
flutterLocalNotificationsPlugin.show(
message.data.hashCode,
message.data['title'],
message.data['body'],
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
importance: Importance.high,
priority: Priority.high,
// sound: RawResourceAndroidNotificationSound(sound.split('.').first),
playSound: true,
icon: '#mipmap/ic_launcher',
),
));
/*NotificationApi.showNotification(
title: message.data['title'],
body: message.data['body'],
payload: "",
id: int.parse(channel.id));*/
}
Future<void> main() async{
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
runApp(MyApps());
// configLoading();
}
class MyApps extends StatefulWidget {
const MyApps({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() {
return MyApp();
}
}
class MyApp extends State<MyApps> {
static ValueNotifier<int> strikeNotifier = ValueNotifier(0);
Color _primaryColor = Color(0xff0d8b75);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return ScreenUtilInit(
builder: () => MaterialApp(
debugShowCheckedModeBanner: false,
home: SplashScreen(),
),
designSize: const Size(1080, 2280),
);
}
void showNotification(String title, String body) async {
await _demoNotification(title, body);
}
Future<void> _demoNotification(String title, String body) async {
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'channel_I', 'channel name',
showProgress: true,
priority: Priority.high,
playSound: true,
ticker: 'test ticker');
var iOSChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics, iOS: iOSChannelSpecifics);
await flutterLocalNotificationsPlugin
.show(0, title, body, platformChannelSpecifics, payload: 'test');
}
#override
void initState() {
super.initState();
FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) {
if (message != null) {
Navigator.push(context, MaterialPageRoute(builder: (context)=>DoneAndPaiedPagess(0)));
}
});
getToken().then((value) {
if(value!=null) {
AppConstants.firebaseToken = value;
}
});
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
new FlutterLocalNotificationsPlugin();
var initializationSettingsAndroid = AndroidInitializationSettings('#mipmap/ic_launcher');
var initializationSettingsIOS = IOSInitializationSettings();
var initializationSettings = InitializationSettings(android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
flutterLocalNotificationsPlugin.initialize(initializationSettings,
);
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
var data = message.data;
// AndroidNotification? android = message.notification?.android;/
if (data != null ) {
if(data['title'].toString().toLowerCase()=="new request") {
SessionManager sessionManager = SessionManager(context);
sessionManager.getBadge().then((badge) {
if (badge != null) {
setState(() {
int x = badge + 1;
strikeNotifier.value = x;
sessionManager.saveBadge(x);
});
}
else {
strikeNotifier.value = 1;
sessionManager.saveBadge(1);
}
});
}
print("entered");
flutterLocalNotificationsPlugin.show(
data.hashCode,
data['title'],
data['body'],
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
playSound: true,
icon: '#mipmap/ic_launcher',
),
));
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
Navigator.push(context, MaterialPageRoute(builder: (context)=>DoneAndPaiedPagess(0)));
});
}
Future<String?> getToken() async{
String? token = await FirebaseMessaging.instance.getToken();
print("token is "+token!);
return token;
}
}
In yaml
firebase_core: ^1.12.0
firebase_messaging: ^11.2.6
dependency_overrides:
firebase_messaging_platform_interface: 3.1.6
Edit : from multiple solutions , I tried the most common solution that I used onMessageOpenedApp in initState but it doesn't enter in it
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
Navigator.push(context, MaterialPageRoute(builder: (context)=>DoneAndPaiedPagess(0)));
});
In your code, you are using the flutter_local_notifications plugin and you are creating local notification when you get a push notification from firebase messaging.
Since the notification is not created by firebase messaging so, you are not getting on tap callback in getInitialMessage and onMessageOpenedApp.
In order to get on tap callback on local notifications, you can pass a callback function while initializing flutter_local_notifications
flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: onSelectNotification);
void selectNotification(String payload) async {
if (payload != null) {
debugPrint('notification payload: $payload');
// Here you can check notification payload and redirect user to the respective screen
await Navigator.push(
context,
MaterialPageRoute<void>(builder: (context) => SecondScreen(payload)),
);
}
}
For more, you can check flutter_local_notifications documentation
On your home widget within initState, check the getInitialMessage value :
// get the remote message when your app opened from push notification while in background state
RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage();
// check if it is exists
if (initialMessage != null) {
// check the data property within RemoteMessage and do navigate based on it
}
Check the firebase flutter documentation here https://firebase.flutter.dev/docs/messaging/notifications/#handling-interaction.
Use onMessageOpenedApp stream to listen when a notification is opened in the foreground or background. When the application is terminated, use getInitialMessage to get a pending notification.

Flutter Notification not showing pop up

Notifications I send with Firebase when the app is open, in the background, and closed work fine.
But I want to pop up, like this:
My codes;
local_notification_service.dart:
class LocalNotificationService {
static final FlutterLocalNotificationsPlugin _notificationsPlugin =
FlutterLocalNotificationsPlugin();
static void initialize(BuildContext context) {
final InitializationSettings initializationSettings =
InitializationSettings(
android: AndroidInitializationSettings("#mipmap/launcher_icon"),
iOS: IOSInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,
));
_notificationsPlugin.initialize(initializationSettings,
onSelectNotification: (String? route) async {
if (route != null) {
Navigator.of(context).pushNamed(route);
}
});
}
static void display(RemoteMessage message) async {
try {
final id = DateTime.now().millisecondsSinceEpoch ~/ 1000;
final NotificationDetails notificationDetails = NotificationDetails(
android: AndroidNotificationDetails(
"kasifkocaeli",
"kasifkocaeli channel",
channelDescription: "kasifkocaeli guzel",
importance: Importance.max,
priority: Priority.high,
));
await _notificationsPlugin.show(
id,
message.notification!.title,
message.notification!.body,
notificationDetails,
payload: message.data["route"],
);
} on Exception catch (e) {
print(e);
}
}
}
main.dart:
Future<void> backgroundHandler(RemoteMessage message) async{
print(message.data.toString());
print(message.notification!.title);
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(backgroundHandler);
runApp(const MyApp());
}
choose_screen.dart:
class _ChoosePageState extends State<ChoosePage> {
#override
void initState() {
super.initState();
LocalNotificationService.initialize(context);
//Bildirime tıklandığında gösterilecek mesaj
FirebaseMessaging.instance.getInitialMessage().then((message) {
if (message != null) {
final routeFromMessage = message.data["route"];
Navigator.of(context).pushNamed(routeFromMessage);
}
});
//forground (uygulama önplandayken)
FirebaseMessaging.onMessage.listen((message) {
if (message.notification != null) {
print(message.notification!.body);
print(message.notification!.title);
}
LocalNotificationService.display(message);
});
//Uygulama arkaplandayken ve kullanıcı tıkladığında
FirebaseMessaging.onMessageOpenedApp.listen((message) {
final routeFromMessage = message.data["route"];
Navigator.of(context).pushNamed(routeFromMessage);
});
}
pubspec.yaml:
firebase_messaging: ^11.2.13
flutter_local_notifications: ^9.4.0
firebase_core: ^1.13.1
cloud_firestore: ^3.1.10
AndroidManifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="notification_app"/>
And this is my watched video (he did the same with me but the notification screen opens on his app, but not for me. The scene where the notification is shown
If you ran the app before setting the Importance to Max, it may have been cached without that. I had the same issue and had to wipe the data of the Android emulator and run it again, and then it worked.
You need to open settings and select notifications, go to your app and select open channel name at the bottom of the screen then tick allow floating notifications

Flutter Local Notifications how to show icon on top menu

Hi my notification works fine it also gives vibrate to phone but the icon and the notification is not showing on screen, u have to slider down and u can see it in upper menu. how can I make to show in screen
The app page, I want to show little icon here
The upper menu on the phone is
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
#override
void initState() {
super.initState();
_advertService.showBanner();
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
final android = AndroidInitializationSettings('#mipmap/ic_launcher');
final iOS = IOSInitializationSettings();
final initSettings = InitializationSettings(android, iOS);
flutterLocalNotificationsPlugin.initialize(initSettings,
onSelectNotification: _onSelectNotification);
}
Future<void> _onSelectNotification(String json) async {
final obj = jsonDecode(json);
if (obj['isSuccess']) {
OpenFile.open(obj['filePath']);
} else {
showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text('Error'),
content: Text('${obj['error']}'),
),
);
}
}
Future<void> _showNotification(Map<String, dynamic> downloadStatus) async {
final android = AndroidNotificationDetails(
'channel id', 'channel name', 'channel description',
priority: Priority.High, importance: Importance.Max);
final iOS = IOSNotificationDetails();
final platform = NotificationDetails(android, iOS);
final json = jsonEncode(downloadStatus);
final isSuccess = downloadStatus['isSuccess'];
await flutterLocalNotificationsPlugin.show(
0, // notification id
isSuccess ? 'Okay' : 'Fail',
isSuccess
? 'Downloaded'
: 'Failed',
platform,
payload: json);
}
first you will set Flutter Launcher Icons
Setup the config file
dev_dependencies:
flutter_launcher_icons: "^0.7.3"
flutter_icons:
android: "launcher_icon"
ios: true
image_path: "assets/icon/icon.png"
If you name your configuration file something other than flutter_launcher_icons.yaml or pubspec.yaml you will need to specify the name of the file when running the package.
Note: If you are not using the existing pubspec.yaml ensure that your config file is located in the same directory as it.
Run the package
flutter pub get
flutter pub run flutter_launcher_icons:main
use this plugin

'MissingPluginException' is not a subtype of type 'String' error in flutter local notification

I tried the following code. It's giving 'MissingPluginException' is not a subtype of type 'String'
Below is the code I used (pasted only notification part here). No issue in flutter doctor also.
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
class _Home extends State<HomePage> with TickerProviderStateMixin {
static FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();
#override
void initState() {
super.initState();
firebaseCloudMessaging_Listeners();
}
void firebaseCloudMessaging_Listeners() {
var android = new AndroidInitializationSettings('mipmap/ic_launcher',);
var ios = new IOSInitializationSettings();
var platform = new InitializationSettings(android, ios);
flutterLocalNotificationsPlugin.initialize(platform,onSelectNotification: onSelectNotification);
if (Platform.isIOS) iOS_Permission();
_firebaseMessaging.getToken().then((token){
//FCM=token;
}).catchError((onError){
print("blb07 "+onError.toString());
});
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print('blb07 on message $message');
handleNotification(message['data']['message']);
},
onResume: (Map<String, dynamic> message) async {
print('blb07 on resume $message');
handleNotification(message['data']['message']);
},
onLaunch: (Map<String, dynamic> message) async {
print('blb07 on launch $message');
handleNotification(message['data']['message']);
},
);
}
void iOS_Permission() {
_firebaseMessaging.requestNotificationPermissions(
IosNotificationSettings(sound: true, badge: true, alert: true)
);
_firebaseMessaging.onIosSettingsRegistered
.listen((IosNotificationSettings settings)
{
print("Settings registered: $settings");
});
}
Future onSelectNotification(String payload) async {
await Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new DisplayNotifications()),
);
}
void handleNotification(String message) async{
var androidPlatformChannelSpecifics = new AndroidNotificationDetails(
'default1', 'Sureworks ', 'Sureworks app notifications',
importance: Importance.Max, priority: Priority.High);
var iOSPlatformChannelSpecifics = new IOSNotificationDetails();
var platformChannelSpecifics = new NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
print("blb07 start");
try{
await flutterLocalNotificationsPlugin.show(0, 'Sureworks', message, platformChannelSpecifics,payload: 'item')
.then((onValue){
print("blb07 finished");
}).catchError((onError)=>print("blb07 "+onError));
print("blb07 hello end line");
}catch(e){
print("blb07 error "+e.toString());
}
}
}
my pubspec.yaml dependencies
dev_dependencies:
flutter_test:
sdk: flutter
http: ^0.11.3+16
shared_preferences: ^0.4.2
firebase_messaging: ^4.0.0+1
firebase_core: ^0.2.5
flutter_launcher_icons: ^0.7.0
paging: ^0.1.0
flutter_local_notifications: ^0.6.1
What could be the problem? messages passing to the handleNotification funtion are string format only. No problem in Receiving notification data from server.
Did you run pod install ?
If not its likely that there is something missing on the native side.
Simply open up a terminal and navigate to your flutter project root.
Then cd into the iOS folder and run pod install.
This should fix your error.
I found the solution. Migrated my Android to AndroidX. Now it's working fine. Spent more than 4 hours on it.
Migrate to AndroidX and "Invalidate caches and restart" did the trick.