Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A GlobalKey was used multiple times inside one widget's child list ERROR #295

Open
mvukojicic opened this issue Feb 1, 2024 · 8 comments
Labels

Comments

@mvukojicic
Copy link

mvukojicic commented Feb 1, 2024

Hi, once I insert credentials for login, on redirecting way back to the app, I get this error. I am using the GetX package for routing and as a wrapper for my root app.

root app
Screenshot 2024-02-01 at 11 14 06

in a separate file, I have the config for authorization.
Screenshot 2024-02-01 at 11 14 47

an then in GetxController I have logic for login, logout...

Screenshot 2024-02-01 at 11 15 23

@mvukojicic mvukojicic reopened this Feb 1, 2024
@AliGuemues
Copy link

I think I had this problem too. My problem was solved after I replaced "initialRoute" with "home" in the class MaterialApp

Copy link

github-actions bot commented Aug 9, 2024

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. If you still think this issue is needed, reopen it again.

@github-actions github-actions bot added the stale label Aug 9, 2024
@Pradeeptharu100
Copy link

Pradeeptharu100 commented Jan 1, 2025

I encountered the same issue while implementing deep linking. The deep link works normally when the app is open, but if the app is closed, an error occurs when clicking on the link to open the app. It displays the error: 'A GlobalKey was used multiple times inside one widget's child list.'"

Let me know if you need further assistance!

Here is my code :

import 'dart:io';
import 'dart:ui';

import 'package:device_preview/device_preview.dart';
import 'package:eShiksha/domains.dart';
import 'package:eShiksha/features/auth/screens/splash_screen.dart';
import 'package:eShiksha/features/course/dt_import_handler.dart';
import 'package:eShiksha/features/notification/screens/notification_screen.dart';
import 'package:eShiksha/features/routes/dt_screens.dart';
import 'package:eShiksha/generic/controller/dependency_injection.dart';
import 'package:eShiksha/generic/controller/dt_shared_pref_controller.dart';
import 'package:eShiksha/get_bindings.dart';
import 'package:eShiksha/logger.dart';
import 'package:eShiksha/network_config.dart';
import 'package:eShiksha/util/deep_link_handler.dart';
import 'package:eShiksha/util/global_keys.dart';
import 'package:eShiksha/util/notification_service.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/services.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_network_library/flutter_network_library.dart';
import 'package:get_storage/get_storage.dart';
import 'package:khalti_flutter/khalti_flutter.dart';
import 'package:no_screenshot/no_screenshot.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await DeepLinkHandler().initPlatformState();
final noScreenshot = NoScreenshot.instance;
bool result = await noScreenshot.screenshotOff();
debugPrint('Screenshot Off: $result');
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
const InitializationSettings initializationSettings =
InitializationSettings(android: initializationSettingsAndroid);
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
await dotenv.load();
await Firebase.initializeApp();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
SharedPrefController prefController = Get.put(SharedPrefController());
await SharedPreferences.getInstance();
prefController.getAllData();
ByteData data =
await PlatformAssetBundle().load('assets/ca/lets-encrypt-r3.pem');
SecurityContext.defaultContext
.setTrustedCertificatesBytes(data.buffer.asUint8List());

await RESTExecutor.initialize(config, domains);

if (Platform.isAndroid) {
await Permission.notification.isDenied.then((value) {
if (value) {
Permission.notification.request();
}
});
}
try {
FirebaseAnalytics.instance.setAnalyticsCollectionEnabled(true);
} catch (e) {
logger.e(e);
}

FirebaseNotificationsService().setUpFirebase();

FirebaseMessaging.onBackgroundMessage(
FirebaseNotificationsService.firebaseMessagingBackgroundHandler);

FirebaseMessaging.instance.subscribeToTopic("general");

FlutterError.onError = (errorDetails) {
FirebaseCrashlytics.instance.recordFlutterFatalError(errorDetails);
};

PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
await GetStorage.init();
DependencyInjection.init();

runApp(
// DevicePreview(
// enabled: true,
// builder: (context) =>
const MyApp(),
// ),
);
}

final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();

class MyApp extends StatefulWidget {
const MyApp({super.key});

@OverRide
State createState() => _MyAppState();
}

class _MyAppState extends State {
@OverRide
void initState() {
super.initState();
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
if (message.notification != null) {}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
handleNotificationTap(message);
});
FirebaseMessaging.instance
.getInitialMessage()
.then((RemoteMessage? message) {
if (message != null) {
handleNotificationTap(message);
}
});
}

void handleNotificationTap(RemoteMessage message) {
Get.to(() => NotificationScreen());
}

@OverRide
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
return KhaltiScope(
navigatorKey: GlobalKeys.navigatorKey,
publicKey: Constants.khaltiPublicKey,
enabledDebugging: true,
builder: (context, navKey) {
return LayoutBuilder(
builder: (context, constraints) {
final designSize =
Size(constraints.maxWidth, constraints.maxHeight);
return ScreenUtilInit(
designSize: designSize,
minTextAdapt: true,
builder: (context, build) {
return MediaQuery(
data:
MediaQuery.of(context).copyWith(textScaleFactor: 0.9),
child: GestureDetectorWrapper(
child: ScrollDetectorWrapper(
child: GetMaterialApp(
unknownRoute: GetPage(
name: "/",
page: () => const SplashScreen(),
),
supportedLocales: const [
Locale('en', 'US'),
Locale('ne', 'NP'),
],
navigatorObservers: [
FirebaseAnalyticsObserver(
analytics: FirebaseAnalytics.instance),
],
builder: EasyLoading.init(),
useInheritedMediaQuery: true,
locale: DevicePreview.locale(context),
navigatorKey: navKey,
localizationsDelegates: const [
KhaltiLocalizations.delegate,
],
debugShowCheckedModeBanner: false,
title: 'eShiksha',
getPages: DTScreens.routes,
initialRoute: DTRoutes.initialScreen,
initialBinding: GetBindings(),
theme: ThemeData(
brightness: Brightness.light,
bottomSheetTheme: const BottomSheetThemeData(
surfaceTintColor: Colors.white),
appBarTheme: Theme.of(context)
.appBarTheme
.copyWith(
systemOverlayStyle: SystemUiOverlayStyle(
statusBarIconBrightness:
Brightness.light,
statusBarBrightness: Brightness.light,
statusBarColor:
DTColor.black.withOpacity(0.15)),
),
scaffoldBackgroundColor: DTColor.primaryDark,
useMaterial3: true,
fontFamily: 'Manrope',
visualDensity:
VisualDensity.adaptivePlatformDensity,
colorScheme:
Theme.of(context).colorScheme.copyWith(
surfaceVariant: Colors.transparent,
),
canvasColor: DTColor.white,
),
),
),
),
);
});
},
);
});
}

bool isTablet(BuildContext context) {
return MediaQuery.of(context).size.shortestSide >= 600;
}
}
//

@mwsean
Copy link

mwsean commented Jan 13, 2025

I encountered the same error using deeplinks. When app is closed before scanning, link breaks. I fixed it by adding a base route to my list of routes: "/"

@mtzzwr
Copy link

mtzzwr commented Jan 20, 2025

I encoutered the same error when I try to open the app by clicking on a Push Notification:

import 'dart:io';

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:get_it/get_it.dart';
import 'package:hypecon/app/core/inject.dart';
import 'package:hypecon/app/core/routes.dart';
import 'package:hypecon/app/presentation/splash/pages/splash_page.dart';
import 'package:hypecon/app/presentation/state_management/theme_store.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:hypecon/app/data/services/secure_storage_service.dart';
import 'package:hypecon/app/helpers/extensions/build_context_ext.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await dotenv.load(fileName: 'env/.env');
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
Inject.init();
if (Platform.isAndroid || Platform.isIOS) Inject.initFcmService();
initializeDateFormatting().then((
) => runApp(const MainApp()));
}

final GlobalKey navigatorKey = GlobalKey();
final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
debugPrint("Mensagem em segundo plano: ${message.data}");
}

class MainApp extends StatelessWidget {
const MainApp({super.key});

@OverRide
Widget build(BuildContext context) {
final themeStore = GetIt.I();
return AnnotatedRegion(
value: SystemUiOverlayStyle.light,
child: MaterialApp(
debugShowCheckedModeBanner: false,
navigatorKey: navigatorKey,
home: const SplashPage(),
onGenerateRoute: onGenerateRoute(),
builder: (context, child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaler: TextScaler.noScaling,
),
child: child!,
);
},
theme: themeStore.currentTheme,
),
);
}
}

void setupFlutterNotifications() async {
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');

const DarwinInitializationSettings initializationSettingsIOS =
DarwinInitializationSettings();

const InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);

await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (details) {
_handleNotification(details);
},
);
}

void showFlutterNotification(RemoteMessage message) {
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(
'notification_channel',
'High Importance Notifications',
importance: Importance.high,
priority: Priority.high,
);

const NotificationDetails platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
);

flutterLocalNotificationsPlugin.show(
message.hashCode,
message.notification?.title,
message.notification?.body,
platformChannelSpecifics,
);
}

void verifyAuthenticationAndHandleNotification(BuildContext context) async {
final storage = SecureStorageService();
final token = await storage.getAccessToken() ?? '';

final initialMessage = await FirebaseMessaging.instance.getInitialMessage();
if (initialMessage != null) {
if (!context.mounted) return;
context.push('/home');
return;
}

FirebaseMessaging.onMessage.listen((RemoteMessage message) {
if (message.notification != null) {
showFlutterNotification(message);
}
});

FirebaseMessaging.onMessageOpenedApp.listen((message) {
_handleNotification(message);
});

Future.delayed(
const Duration(seconds: 3),
() {
if (context.mounted) {
if (token.isEmpty) {
Navigator.pushNamedAndRemoveUntil(
context,
'/onboarding',
(route) => false,
);
return;
}
Navigator.pushNamedAndRemoveUntil(context, '/home', (route) => false);
}
},
);
}

void handleNotification(dynamic message) {
final route = message.data['route'];
final id = message.data['mission_id'];
WidgetsBinding.instance.addPostFrameCallback((
) {
if (route != null) {
navigatorKey.currentState?.pushNamedAndRemoveUntil(
route,
(route) => false,
arguments: id,
);
return;
} else {
navigatorKey.currentState?.pushNamedAndRemoveUntil(
'/home',
(route) => false,
);
return;
}
});
}

@Pradeeptharu100
Copy link

"Defining the unknownRoute in MaterialApp can solve my problem."
Let me know if you'd like further explanation or adjustments!

@Pradeeptharu100
Copy link

I encoutered the same error when I try to open the app by clicking on a Push Notification:

import 'dart:io';

import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:get_it/get_it.dart'; import 'package:hypecon/app/core/inject.dart'; import 'package:hypecon/app/core/routes.dart'; import 'package:hypecon/app/presentation/splash/pages/splash_page.dart'; import 'package:hypecon/app/presentation/state_management/theme_store.dart'; import 'package:intl/date_symbol_data_local.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:hypecon/app/data/services/secure_storage_service.dart'; import 'package:hypecon/app/helpers/extensions/build_context_ext.dart';

void main() async { WidgetsFlutterBinding.ensureInitialized(); await dotenv.load(fileName: 'env/.env'); await Firebase.initializeApp(); FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler); Inject.init(); if (Platform.isAndroid || Platform.isIOS) Inject.initFcmService(); initializeDateFormatting().then(() => runApp(const MainApp())); }

final GlobalKey navigatorKey = GlobalKey(); final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async { debugPrint("Mensagem em segundo plano: ${message.data}"); }

class MainApp extends StatelessWidget { const MainApp({super.key});

@OverRide Widget build(BuildContext context) { final themeStore = GetIt.I(); return AnnotatedRegion( value: SystemUiOverlayStyle.light, child: MaterialApp( debugShowCheckedModeBanner: false, navigatorKey: navigatorKey, home: const SplashPage(), onGenerateRoute: onGenerateRoute(), builder: (context, child) { return MediaQuery( data: MediaQuery.of(context).copyWith( textScaler: TextScaler.noScaling, ), child: child!, ); }, theme: themeStore.currentTheme, ), ); } }

void setupFlutterNotifications() async { const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher');

const DarwinInitializationSettings initializationSettingsIOS = DarwinInitializationSettings();

const InitializationSettings initializationSettings = InitializationSettings( android: initializationSettingsAndroid, iOS: initializationSettingsIOS, );

await flutterLocalNotificationsPlugin.initialize( initializationSettings, onDidReceiveNotificationResponse: (details) { _handleNotification(details); }, ); }

void showFlutterNotification(RemoteMessage message) { const AndroidNotificationDetails androidPlatformChannelSpecifics = AndroidNotificationDetails( 'notification_channel', 'High Importance Notifications', importance: Importance.high, priority: Priority.high, );

const NotificationDetails platformChannelSpecifics = NotificationDetails( android: androidPlatformChannelSpecifics, );

flutterLocalNotificationsPlugin.show( message.hashCode, message.notification?.title, message.notification?.body, platformChannelSpecifics, ); }

void verifyAuthenticationAndHandleNotification(BuildContext context) async { final storage = SecureStorageService(); final token = await storage.getAccessToken() ?? '';

final initialMessage = await FirebaseMessaging.instance.getInitialMessage(); if (initialMessage != null) { if (!context.mounted) return; context.push('/home'); return; }

FirebaseMessaging.onMessage.listen((RemoteMessage message) { if (message.notification != null) { showFlutterNotification(message); } });

FirebaseMessaging.onMessageOpenedApp.listen((message) { _handleNotification(message); });

Future.delayed( const Duration(seconds: 3), () { if (context.mounted) { if (token.isEmpty) { Navigator.pushNamedAndRemoveUntil( context, '/onboarding', (route) => false, ); return; } Navigator.pushNamedAndRemoveUntil(context, '/home', (route) => false); } }, ); }

void handleNotification(dynamic message) { final route = message.data['route']; final id = message.data['mission_id']; WidgetsBinding.instance.addPostFrameCallback(() { if (route != null) { navigatorKey.currentState?.pushNamedAndRemoveUntil( route, (route) => false, arguments: id, ); return; } else { navigatorKey.currentState?.pushNamedAndRemoveUntil( '/home', (route) => false, ); return; } }); }

"Defining the unknownRoute in MaterialApp can solve my problem."

Let me know if you'd like further explanation or adjustments!

@mtzzwr
Copy link

mtzzwr commented Jan 20, 2025

Still the same error. I don't know what can be

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants