i have implemented one application which supports firebase notifications My app worked fine before. but when I merge my notification branch, my app stops working. when i launch my application on iOS, it shows this error
Connecting to VM Service at ws://127.0.0.1:49769/gMyOshYEY=/ws
flutter: dependOnInheritedWidgetOfExactType<MediaQuery>() or dependOnInheritedElement() was called before _LoginScreenState.initState() was completed.
When an inherited widget changes, for example, if the value of Theme.of() changes, its dependent widgets are rebuilt. If the dependent widget's reference to the inherited widget is in a constructor or an initState() method, then the rebuilt dependent widget will not reflect the changes in the inherited widget.
Typically, references to inherited widgets should occur in widget build() methods. Alternatively, initialization based on inherited widgets can be placed in the didChangeDependencies method, which is called after initState and whenever the dependencies change thereafter.
flutter: [core/no-app] No Firebase App '[DEFAULT]' has been created.
and when i reload my application, i get this error
═ Exception caught by widgets library ═══════════════════════════════════
The following FirebaseException was thrown building _InheritedProviderScope<BannersBloc?>(value: <not yet loaded>):
[core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()
The relevant error-causing widget was:
BlocProvider<BannersBloc> BlocProvider:file:///Users/admin/Documents/NadiTarangini/nt_guna/lib/main.dart:196:48
When the exception was thrown, this was the stack:
#0 MethodChannelFirebase.app (package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart:193:5)
method_channel_firebase.dart:193
#1 Firebase.app (package:firebase_core/src/firebase.dart:56:41)
firebase.dart:56
#2 FirebaseMessaging.instance (package:firebase_messaging/src/messaging.dart:32:47)
messaging.dart:32
#3 new NotificationManager (package:nadi_tarangini/DashboardScreen/AppBar/notification/controller/notification_manager.dart:18:66)
notification_manager.dart:18
#4 new _DashboardState (package:nadi_tarangini/DashboardScreen/screens/dashboard.dart:48:51)
dashboard.dart:48
#5 Dashboard.createState (package:nadi_tarangini/DashboardScreen/screens/dashboard.dart:40:37)
dashboard.dart:40
#6 new StatefulElement (package:flutter/src/widgets/framework.dart:5564:25)
framework.dart:5564
#7 StatefulWidget.createElement (package:flutter/src/widgets/framework.dart:776:38)
framework.dart:776
... Normal element mounting (7 frames)
#14 _InheritedProviderScopeElement.mount (package:provider/src/inherited_provider.dart:411:11)
inherited_provider.dart:411
... Normal element mounting (7 frames)
#21 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222:11)
but it is working perfect in my android application
here is my code
@pragma('vm:entry-point')
List<NotificationModel> notificationsList = [];
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
Handle background messages here
String? notificationTitle = message.notification?.title;
String? notificationBody = message.notification?.body;
if (notificationTitle != null && notificationBody != null) {
notificationsList = await NotificationManager().getNotificationsFromApi();
int badgeCount = notificationsList.where((n) =>!n.isRead). length;
FlutterAppBadger.updateBadgeCount(badgeCount);
sendNotificationUnreadCount.add({'badgeCount': badgeCount, 'notifications': notificationsList});
}
}
MaterialColor appclr = const MaterialColor(
0xFF00B3DC, // The primary value of the color
<int, Color>{
50: Color (0xFFE6F7FB), // Shade 50
100: Color (0xFFB3E2F0), // Shade 100
200: Color (0xFF80CCE6), // Shade 200
300: Color (0xFF4DA7DB), // Shade 300
400: Color (0xFF267EA3), // Shade 400
500: Color (0xFF00B3DC), // Shade 500 (the primary color)
600: Color (0xFF008FA7), // Shade 600
700: Color (0xFF00728B), // Shade 700
800: Color (0xFF00566F), // Shade 800
900: Color (0xFF003A54), // Shade 900
},
);
void main() async {
WidgetsFlutterBinding.ensureInitialized();
ByteData data =
await PlatformAssetBundle().load('assets/ca/lets-encrypt-r3.pem');
final context = SecurityContext.defaultContext;
context.setTrustedCertificatesBytes(data.buffer.asUint8List());
context.allowLegacyUnsafeRenegotiation = true;
HttpOverrides.global = MyHttpOverrides();
try {
await Firebase.initializeApp();
// FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
// alert: true, badge: true, sound: true);
// log("Firebase Initialized");
} catch (e) {
// print("Firebase initialization failed: $e");
}
Bloc.observer = MyBlocObserver();
runApp(const MyApp());
}
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
// BlocProvider<AppBarBloc>(
// create: (context) => AppBarBloc(context: context)),
BlocProvider<BannersBloc>(
create: (context) => BannersBloc(context: context)),
BlocProvider<ReferralsBloc>(
create: (context) => ReferralsBloc(context: context)
BlocProvider<BlogsBloc>(
create: (context) => BlogsBloc(context: context)),
BlocProvider<AppointmentBloc>(
create: (context) => AppointmentBloc(context: context)),
BlocProvider<IconContainerBloc>(
create: (context) => IconContainerBloc(context: context)),
BlocProvider<PatientScreenBloc>(
create: (context) => PatientScreenBloc(context: context)),
// Add more BlocProviders if needed
],
child: Sizer(
builder: (context, orientation, deviceType) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Nadi Tarangini',
navigatorKey: AppNavigator.navigatorKey,
theme: ThemeData(
primarySwatch: appclr,
useMaterial3: false,
fontFamily: 'Roboto-Bold',
appBarTheme: const AppBarTheme(
backgroundColor:
ColorConstants.ntBlue, // Set the global AppBar color here
),
),
initialRoute: "/",
onGenerateRoute: (RouteSettings settings) {
if (settings.name == RecipeScreen.routeName) {
final Map<String, dynamic> data =
settings.arguments as Map<String, dynamic>;
return MaterialPageRoute(builder: (context) {
return RecipeScreen(recipeData: data);
});
}
return null;
},
routes: {
"/": (context) => const SplashScreen(),
"/OnboardingScreen": (context) => const OnboardingScreen(),
"/SignUpOnboardingScreen": (context) =>
const SignUpOnboardingScreen(),
"/PersonalScreen": (context) => const PersonalScreen(),
"/ProfessionalScreen": (context) => const ProfessionalScreen(),
"/ClinicScreen": (context) => const ClinicScreen(),
"/CredentialScreen": (context) => const CredentialScreen(),
"/LoginScreen": (context) => const LoginScreen(),
"/OtpVerificationScreen": (context) =>
const OtpVerificationScreen(),
"/ForgotPasswordScreen": (context) =>
const ForgotPasswordScreen(),
"/CreateAccountScreen": (context) => const CreateAccountScreen(),
"/ClinicDetailsScreen": (context) => const ClinicDetailsScreen(),
"/SyncScreen": (context) => const SyncScreen(),
"/SettingsScreen": (context) => const SettingsScreen(),
"/LinkDeviceScreen": (context) => const LinkDeviceScreen(),
"/DeviceSubscription": (context) => const DeviceSubscription(),
"/HelpScreen": (context) => const HelpScreen(),
// "/DashboardScreen": (context) => const DashboardScreen(),
"/DashboardScreen": (context) => BlocProvider(
create: (context) => BannersBloc(context: context),
child: const Dashboard(),
),
"/PatientsScreen": (context) => const PatientsScreen(),
"/PatientScreen": (context) => const PatientListScreen(),
"/PatientQueriesScreen": (context) =>
const PatientQueriesScreen(),
"/AddPatientScreen": (context) => const AddPatientScreen(),
"/NadiCaptureScreen": (context) => const NadiParikshaScreen(),
"/NadiDisplayScreen": (context) => const NadiDisplayScreen(),
"/AppointmentViewScreen": (context) =>
const AppointmentViewScreen(),
// "/AppointmentDiaryScreen": (context) => const AppointmentDiaryScreen(),
"/UpdateDoctorDetailsScreen": (context) =>
const UpdateDoctorDetailsScreen(),
"/AddAppointmentScreen": (context) =>
const AddAppointmentScreen(),
"/PendingAppointmentScreen": (context) =>
const PendingAppointmentScreen(),
"/MissedAppointmentScreen": (context) =>
const MissedAppointmentScreen(),
"/EditAppointmentScreen": (context) =>
const EditAppointmentScreen(),
"/AppointmentHistoryScreen": (context) =>
const AppointmentHistoryScreen(),
"/NotificationScreen": (context) => NotificationScreen(),
///Patinet Routes
"/PatientRegistrationScreen": (context) =>
const PatientRegistrationScreen(),
"/PatientsHomeScreen": (context) => const PatientsHomeScreen(),
"/UpdatePatientDetailsScreen": (context) =>
const UpdatePatientDetailsScreen(),
"/ReferralHistory": (context) => const ReferralHistory(),
"/EditPatient": (context) => const EditAllDataPatient(),
"/EditAnonymousPatient": (context) => const EditAnonymous(),
"/DrawerMenu": (context) => DrawerMenu(),
"/ChangePasswordScreen": (context) =>
const ChangePasswordScreen(),
},
);
},
),
);
}
}
this is my notification manager class
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
List<NotificationModel> notificationsList = [];
// Generate a unique notification ID based on the current timestamp
int badgeCount = 0; // Add badgeCount variable
final List<Function(dynamic)> _listeners = [];
void addNotificationListener(Function(dynamic) listener) {
_listeners.add(listener);
}
void removeNotificationListener(Function(dynamic) listener) {
_listeners.remove(listener);
}
void notifyListeners(dynamic notification) {
for (final listener in _listeners) {
listener(notification);
}
}
void init() {
// Initialize FlutterLocalNotificationsPlugin
const initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
DarwinInitializationSettings initializationSettingsDarwin =
const DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
defaultPresentBanner: true,
);
final initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsDarwin);
flutterLocalNotificationsPlugin.initialize(
initializationSettings,
// onDidReceiveBackgroundNotificationResponse: (details) {
// Navigator.pushNamedAndRemoveUntil(
// AppNavigator.navigatorKey.currentContext!,
// "/AppointmentViewScreen",
// (route) => false);
// },
onDidReceiveNotificationResponse: (details) async {
List<NotificationModel> navNotifications = await getNotificationsFromApi();
// print("print receive: ${ModalRoute.of(AppNavigator.navigatorKey.currentContext!)}");
// Navigator.of( AppNavigator.navigatorKey.currentContext!,).pushAndRemoveUntil(MaterialPageRoute(builder: (context) =>
// NotificationScreen(notifications: navNotifications)), (Route<dynamic> route) => false);
// print("all details $details");
if (details.payload?.contains("appointment")?? false) {
Navigator.pushNamedAndRemoveUntil(
AppNavigator.navigatorKey.currentContext!,
"/AppointmentViewScreen",
(route) => false);
}else{
Navigator.pushAndRemoveUntil<void>(
AppNavigator.navigatorKey.currentContext!,
MaterialPageRoute<void>(builder: (BuildContext context) => NotificationScreen(notifications: navNotifications)),
ModalRoute.withName('/DashboardScreen'),
);
}
},
);
// Request permission to receive notifications
_firebaseMessaging.requestPermission();
// Handle notifications when the app is in the foreground
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
_handleNotification(message,false);
print("foreground");
});
// Handle notifications when the app is in the background and opened by the user
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async {
_handleNotification(message,true);
print("background");
});
// Initialize badge count
FlutterAppBadger.updateBadgeCount(0);
// Register the background message handler
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
// Retrieve the FCM token
_firebaseMessaging.getToken().then((String? token) {
if (kDebugMode) {
print("FCM Token: $token");
}
});
}
Future<List<NotificationModel>> getNotificationsFromApi() async {
try {
final response = await ApiProvider().fetchNotificationsData(context: AppNavigator.navigatorKey.currentContext!);
final List<dynamic> jsonList = response['notifications_data'];
List<NotificationModel> notifications = jsonList.map((json) => NotificationModel.fromJson(json)).toList();
notifications.sort((a, b) => b.timestamp.compareTo(a.timestamp));
notifications = notifications;
return notifications;
} catch (e) {
if (kDebugMode) {
print('Error fetching notifications: $e');
}
return [];
}
}
void _handleNotification(RemoteMessage message,bool navigate) async {
bool appAlreadyOpen = isAppAlreadyOpen();
print("is app open: $appAlreadyOpen");
String? notificationType = message.data['notification_type'] ?? '';
String? notificationTitle = message.notification?.title;
String? notificationBody = message.notification?.body;
if (notificationTitle != null && notificationBody != null) {
// Display the notification in the system tray
const androidPlatformChannelSpecifics = AndroidNotificationDetails(
'nadi_tarangini',
'nadi_tarangini_notifications',
importance: Importance.high,
priority: Priority.high,
);
const platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
);
int notificationId = DateTime.now().millisecondsSinceEpoch ~/ 1000;
// Create a NotificationModel object
final newNotification = NotificationModel(
id: notificationId,
title: notificationTitle,
body: notificationBody,
type: notificationType!,
timestamp: DateTime.now(),
);
// Add the notification to the list
// notifications = await getNotificationsFromApi();
notificationsList.add(newNotification);
await updateDashboardNotificationCount();
await flutterLocalNotificationsPlugin.show(
notificationId,
notificationTitle,
notificationBody,
platformChannelSpecifics,
payload: notificationBody,
);
if (kDebugMode) {
print("Received Notification: $notificationTitle - $notificationBody");
}
if (notificationBody.contains("appointment") && navigate) {
Navigator.pushNamedAndRemoveUntil(
AppNavigator.navigatorKey.currentContext!,
"/AppointmentViewScreen",
(route) => false);
} else if (navigate) {
Navigator.pushAndRemoveUntil<void>(
AppNavigator.navigatorKey.currentContext!,
MaterialPageRoute<void>(builder: (BuildContext context) => NotificationScreen(notifications: notifications)),
ModalRoute.withName('/DashboardScreen'));
// AppNavigator.navigatorKey.currentContext!,
// MaterialPageRoute(
// builder: (context) => NotificationScreen(
// notifications: notifications,
// ),
// ),
// );
}
}
}
Future<void> markNotificationAsRead(List<NotificationModel> notifications,
int notificationId, int index) async {
if (index != -1 && !notifications[index].isRead) {
notifications[index].isRead = true;
await ApiProvider().markNotificationAsUnreadForDoc(
context: AppNavigator.navigatorKey.currentContext!,
notificationId: notificationId,
);
await updateDashboardNotificationCount();
}
}
Future<void> updateDashboardNotificationCount() async {
List<NotificationModel> notifications = await getNotificationsFromApi();
badgeCount = notifications.where((n) => !n.isRead).length;
FlutterAppBadger.updateBadgeCount(badgeCount);
sendNotificationUnreadCount.add({'badgeCount': badgeCount, 'notifications': notifications});
}
bool isAppAlreadyOpen() {
return RendererBinding.instance.hasScheduledFrame;
}```
[1]: https://i.stack.imgur.com/ZjH56.jpg