Created
June 29, 2020 12:20
-
-
Save Ramesh-X/fba266d526e1322cba1931110cf06a35 to your computer and use it in GitHub Desktop.
FCM Flutter, Navigate on Notification Click
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:bloc/bloc.dart'; | |
import 'package:cloud_firestore/cloud_firestore.dart'; | |
import 'package:firebase_messaging/firebase_messaging.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter/scheduler.dart'; | |
import 'package:flutter_bloc/flutter_bloc.dart'; | |
// Start the App | |
void main() => runApp(MainApp()); | |
// Base Event Class | |
class UtilEvent {} | |
class NavigateToView extends UtilEvent { | |
final String path; | |
NavigateToView(this.path); | |
} | |
// Base State Class | |
class UtilState {} | |
class NavigateToSecond extends UtilState { | |
final DocumentReference ref; | |
NavigateToSecond(this.ref); | |
} | |
class NoNavigation extends UtilState {} | |
// BLoC that will handle the `onNotificationClick` triggers | |
class UtilBloc extends Bloc<UtilEvent, UtilState> { | |
UtilBloc() { | |
final _firebaseMessaging = FirebaseMessaging(); | |
// Setup FCM token and do other stuff | |
_firebaseMessaging.configure( | |
onMessage: (Map<String, dynamic> message) async { | |
print('on message $message'); | |
}, | |
onResume: (Map<String, dynamic> message) async { | |
print('on resume $message'); | |
final path = message['data']['userRef']; | |
add(NavigateToView(path)); | |
}, | |
onLaunch: (Map<String, dynamic> message) async { | |
print('on launch $message'); | |
final path = message['data']['userRef']; | |
add(NavigateToView(path)); | |
}, | |
); | |
} | |
@override | |
UtilState get initialState => NoNavigation(); | |
@override | |
Stream<UtilState> mapEventToState(UtilEvent event) async* { | |
switch (event.runtimeType) { | |
case NavigateToView: | |
final e = event as NavigateToView; | |
if (e.path?.isEmpty ?? true) { | |
yield NoNavigation(); | |
break; | |
} | |
yield NavigateToSecond(Firestore.instance.document(e.path)); | |
break; | |
} | |
} | |
} | |
// Main Material App | |
class MainApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return BlocProvider<UtilBloc>( | |
create: (context) => UtilBloc(), | |
child: MaterialApp( | |
home: FirstPage(), | |
), | |
); | |
} | |
} | |
// First page with Reference List | |
class FirstPage extends StatelessWidget { | |
// This method will navigate the app to the `SecondPage` to show the data in the given `DocumentReference` | |
void navigateToSecondView(BuildContext context, DocumentReference ref) { | |
Navigator.push( | |
context, | |
MaterialPageRoute( | |
builder: (context) => SecondPage(ref: ref), | |
)); | |
} | |
final refs = <DocumentReference>[]; | |
@override | |
Widget build(BuildContext context) { | |
final bloc = BlocProvider.of<UtilBloc>(context); | |
return BlocBuilder<UtilBloc, UtilState>( | |
builder: (context, state) { | |
if (state is NavigateToSecond) { | |
bloc.add(NavigateToView(null)); | |
SchedulerBinding.instance.addPostFrameCallback((_) { | |
navigateToSecondView(context, state.ref); | |
}); | |
} | |
return Scaffold( | |
body: Center( | |
child: ListView.builder( | |
itemCount: refs.length, | |
itemBuilder: (context, i) => | |
ListTile( | |
title: Text(refs[i].path), | |
onTap: () => navigateToSecondView(context, refs[i]), | |
), | |
), | |
), | |
); | |
} | |
); | |
} | |
} | |
// This page will show the data in the documet refered by the given `DocumentReference` | |
class SecondPage extends StatefulWidget { | |
final DocumentReference ref; | |
const SecondPage({ | |
Key key, | |
@required this.ref, | |
}) : super(key: key); | |
@override | |
_SecondPageState createState() => _SecondPageState(); | |
} | |
class _SecondPageState extends State<SecondPage> { | |
Future<Map<String, dynamic>> data; | |
@override | |
void initState() { | |
super.initState(); | |
data = mapData(); | |
} | |
@override | |
void didUpdateWidget(SecondPage oldWidget) { | |
super.didUpdateWidget(oldWidget); | |
if (oldWidget.ref.path != widget.ref.path) { | |
data = mapData(); | |
} | |
} | |
Future<Map<String, dynamic>> mapData() async { | |
return (await widget.ref.get()).data; | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: FutureBuilder<Map<String, dynamic>>( | |
future: data, | |
builder: (context, snapshot) { | |
if (snapshot.hasData) { | |
final name = snapshot.data['name']; | |
final email = snapshot.data['email']; | |
return Column( | |
children: <Widget>[ | |
Text("Name: $name"), | |
Text("Email: $email"), | |
], | |
); | |
} | |
return CircularProgressIndicator(); | |
} | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment