Estou tentando essa lógica de que se houver OrderId nos dados de notificação, ele deve abrir OrdersScreen, caso contrário, abrir a tela padrão, mas há OrderId nos dados, mas ainda abre a tela padrão. Não sei. Alguém pode consertar isso?
Tela inicial
class _MyHomeScreenState extends State<MyHomeScreen>
with SingleTickerProviderStateMixin {
int _currentPage = 0;
final PageController _pageController = PageController();
Timer? _timer;
bool _isConnected = true;
bool _hasError = false;
//NOTIFICATION
Future<void> _initializeFCM() async {
FirebaseMessaging messaging = FirebaseMessaging.instance;
// Request notification permissions
NotificationSettings settings = await messaging.requestPermission(
alert: true,
badge: true,
sound: true,
);
if (settings.authorizationStatus == AuthorizationStatus.authorized) {
final apnsToken = await FirebaseMessaging.instance.getAPNSToken();
print('Apns: $apnsToken');
print('User granted permission');
final fcmToken = await FirebaseMessaging.instance.getToken();
if (fcmToken != null) {
print('FCM Token: $fcmToken');
}
} else {
print('User declined or has not accepted permission');
}
// Handle background messages
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
print('🔔 Received a foreground notification:');
print('📨 Message Data: ${message.data}');
print('📄 Notification Title: ${message.notification?.title}');
print('📄 Notification Body: ${message.notification?.body}');
await _showNotification(
message.notification?.title,
message.notification?.body,
);
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print("Notification clicked: ${message.data}");
_handleNotificationNavigation(message.data);
});
RemoteMessage? initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
if (initialMessage != null) {
print(
"App opened from terminated state via notification: ${initialMessage.data}");
_handleNotificationNavigation(initialMessage.data);
}
}
void _handleNotificationNavigation(Map<String, dynamic> data) async {
final String? orderId = data['orderId'];
await Future.delayed(const Duration(seconds: 5));
if (orderId != null && orderId.isNotEmpty) {
Navigator.of(context).push(
MaterialPageRoute(builder: (ctx) => OrdersScreen()),
);
} else {
Navigator.of(context).push(
MaterialPageRoute(builder: (ctx) => BottomBars()),
);
}
}
Future<void> _showNotification(String? title, String? body) async {
const AndroidNotificationDetails androidDetails =
AndroidNotificationDetails(
'your_channel_id',
'your_channel_name',
icon: '@mipmap/ic_launcher',
channelDescription: 'Your channel description',
importance: Importance.high,
priority: Priority.high,
);
const NotificationDetails platformDetails =
NotificationDetails(android: androidDetails);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
await flutterLocalNotificationsPlugin.show(
0, // notification ID
title, // notification title
body, // notification body
platformDetails,
);
}
Future<void> _firebaseMessagingBackgroundHandler(
RemoteMessage message) async {
await Firebase.initializeApp();
print("Handling a background message: ${message.messageId}");
final data = message.data;
_handleNotificationNavigation(data);
}
Future<void> _callPostAPI() async {
final prefs = await SharedPreferences.getInstance();
final alreadyCalled = prefs.getBool('apiCalledThisLaunch') ?? false;
if (alreadyCalled) {
print("API already called for this app launch");
return;
}
final fcmToken = await FirebaseMessaging.instance.getToken();
if (fcmToken == null) {
print("Failed to fetch FCM Token");
return;
}
final accessToken = prefs.getString('accessToken');
if (accessToken == null) {
print("Access token not found");
return;
}
final platform = Platform.isAndroid
? "android"
: Platform.isIOS
? "ios"
: "unknown";
final requestBody = {
"token": fcmToken,
"platform": platform,
};
final url = Uri.parse('');
try {
final response = await http.post(
url,
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer $accessToken",
},
body: json.encode(requestBody),
);
if (response.statusCode == 200) {
final responseData = json.decode(response.body);
print(responseData);
print("API called successfully");
await prefs.setBool('apiCalledThisLaunch', true);
} else {
print("Failed to call API: ${response.statusCode}");
}
} catch (e) {
print("Error calling API: $e");
}
}
Não sei se algo deve mudar no Main.dart também
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
try {
await Firebase.initializeApp();
print("Handling a background message: ${message.messageId}");
} catch (e) {
print("Error handling background message: $e");
}
}
Future<void> _firebaseMessagingAppOpenHandler(RemoteMessage message) async {
try {
await Firebase.initializeApp();
print("Handling a App open message: ${message.messageId}");
} catch (e) {
print("Error handling App open message: $e");
}
}
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
void initializeNotifications() async {
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('');
final InitializationSettings initializationSettings =
InitializationSettings(android: initializationSettingsAndroid);
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final prefs = await SharedPreferences.getInstance();
await prefs.setBool('apiCalledThisLaunch', false);
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
FirebaseMessaging.onMessageOpenedApp.listen(_firebaseMessagingAppOpenHandler);
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print(
'Received a message while in the foreground: ${message.notification?.title}');
});
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => ProfileProvider()),
ChangeNotifierProvider(create: (context) => SignupProvider()),
ChangeNotifierProvider(create: (context) => Cart()),
ChangeNotifierProvider(create: (context) => AddressProvider()),
ChangeNotifierProvider(create: (context) => FavoriteProvider()),
],
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
brightness: Brightness.light,
),
darkTheme: ThemeData(
brightness: Brightness.light,
),
themeMode: ThemeMode.light,
home: const SplashScreen(),
routes: {
'/cart': (context) => const CartScreen(),
'/orders': (context) => OrdersScreen(),
'/default': (context) => BottomBars(),
},
);
}
}
nos logs há um orderId chegando ainda abre a tela de detalhes
D/FLTFireMsgReceiver( 8640): broadcast received for message
I/flutter ( 8640): Received a message while in the foreground: Hurray!
I/flutter ( 8640): 🔔 Received a foreground notification:
I/flutter ( 8640): 📨 Message Data: {orderId: 676e8e92cf1c97006a3a981c, click_action: FLUTTER_NOTIFICATION_CLICK}
I/flutter ( 8640): 📄 Notification Title: Hurray!
I/flutter ( 8640): 📄 Notification Body: Your order has been confirmed 😃
Com base na sua pergunta, a imagem abaixo mostra quando usar cada método para extrair as informações de notificação. Além disso, consulte o novo payload de notificação, pois o antigo está obsoleto.