0

I think I have method that involves setting to go to the notifications tab like this:

class NotificationUtil {

static void subscribeToNotifications(BuildContext context, GlobalKey<ScaffoldState> scaffoldKey) async {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
_firebaseMessaging.configure(
  onMessage: (Map<String, dynamic> message) async {
    print("onMessage: $message");
    _showNotification(scaffoldKey, message);
  },
  onLaunch: (Map<String, dynamic> message) async {
    print("onLaunch: $message");
    await PreferenceUtil.setNotificationKey();
  },
  onResume: (Map<String, dynamic> message) async {
    print("onResume: $message");
    await PreferenceUtil.setNotificationKey();
  },
);

await _firebaseMessaging.getToken();
_firebaseMessaging.requestNotificationPermissions(
    const IosNotificationSettings(sound: true, badge: true, alert: true));
_firebaseMessaging.onIosSettingsRegistered
    .listen((IosNotificationSettings settings) {
  print("Settings registered: $settings");
});

FirebaseUser firebaseUser = await AuthUtil.getFirebaseUser();
_firebaseMessaging
    .subscribeToTopic(firebaseUser.email.replaceAll('@', '%'));
}

 static void _showNotification(GlobalKey<ScaffoldState>  scaffoldKey, Map<String, dynamic> message) {
scaffoldKey.currentState.showSnackBar(new SnackBar(
  content: new Text(message['notification']['body'] as String),
));
 }
 }

But it looks like initState is not called when resuming from the background.

  @override
  void initState() {
super.initState();
PreferenceUtil.showNotifications().then((showNotification) async {
  print("the show notification state is:" +showNotification.toString());
  await PreferenceUtil.clearNotificationKey();
  if (showNotification) {
    setState(() {
      _selectedIndex = 1;
    });
  }
});

}

dazza5000
  • 7,075
  • 9
  • 44
  • 89

1 Answers1

1

The overall approach is to pass in an int to the screen that identifies the tab position to select when the screen with the bottom bar is navigated to.

class MainPage extends StatefulWidget {
  final int selectedIndex;

  MainPage(this.selectedIndex);

  @override
  _MainPageState createState() => _MainPageState(selectedIndex);
}

I had to put in a mechanism to keep track of the current push notification that is being processed because processing would go into an infinite loop when opening the app from a push notification.

This is a more completed implementation that worked for me.

Notification Handling:

class NotificationUtil {
static void subscribeToNotifications(
  BuildContext context, GlobalKey<ScaffoldState> scaffoldKey) async {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
_firebaseMessaging.configure(
  onMessage: (Map<String, dynamic> message) async {
    print("onMessage: $message");
    _showNotification(scaffoldKey, message);
  },
  onLaunch: (Map<String, dynamic> message) async {
    print("onLaunch: $message");
    processIncomingNotification(context, message);
  },
  onResume: (Map<String, dynamic> message) async {
    print("onResume: $message");
    processIncomingNotification(context, message);
  },
);

await _firebaseMessaging.getToken();
_firebaseMessaging.requestNotificationPermissions(
    const IosNotificationSettings(sound: true, badge: true, alert: true));
_firebaseMessaging.onIosSettingsRegistered
    .listen((IosNotificationSettings settings) {
  print("Settings registered: $settings");
});

FirebaseUser firebaseUser = await AuthUtil.getFirebaseUser();
_firebaseMessaging
    .subscribeToTopic(firebaseUser.email.replaceAll('@', '%'));
}

static void processIncomingNotification(BuildContext context, Map<String, dynamic> message) async {
String incomingMessage = message["data"]["google.message_id"] as String;
String currentMessage = await PreferenceUtil.getCurrentMessage();
if (incomingMessage == currentMessage) {
  return;
}
await PreferenceUtil.setCurrentMessage(incomingMessage);
Navigator.pushReplacementNamed(context, "/notifications");
}

static void _showNotification(
  GlobalKey<ScaffoldState> scaffoldKey, Map<String, dynamic> message) {
scaffoldKey.currentState.showSnackBar(new SnackBar(
  content: new Text(message['notification']['body'] as String),
));
}
}

Using named route to select tab:

   class MyApp extends StatelessWidget {
 @override
Widget build(BuildContext context) {
return MaterialApp(
  debugShowCheckedModeBanner: false,
  title: COMPANY_NAME,
  theme: ThemeData.light().copyWith(
      primaryColor: const Color(0xFF13172a),
      accentColor: const Color(0xFFA8C048)),
  home: HomePage(title: COMPANY_NAME),
  routes: {
    '/notifications': (context) => MainPage(1),
  }
);
}
}

MainPage (abbreviated):

class MainPage extends StatefulWidget {
  final int selectedIndex;

  MainPage(this.selectedIndex);

  @override
  _MainPageState createState() => _MainPageState(selectedIndex);
}

class _MainPageState extends State<MainPage> {
  GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
  int _selectedIndex = 0;

  final _widgetOptions = [
    PropertyListPage(),
    NotificationListPage(),
    MorePage(),
  ];

  _MainPageState(this._selectedIndex);
dazza5000
  • 7,075
  • 9
  • 44
  • 89