Skip to content

Instantly share code, notes, and snippets.

@Ramesh-X
Created June 29, 2020 12:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Ramesh-X/fba266d526e1322cba1931110cf06a35 to your computer and use it in GitHub Desktop.
Save Ramesh-X/fba266d526e1322cba1931110cf06a35 to your computer and use it in GitHub Desktop.
FCM Flutter, Navigate on Notification Click
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