Using a BuildContext when receiving a FlutterFire push notification - firebase

In order to do download and save a File on the native side of the app when receiving a push notification, we need to have a BuildContext when receiving it from FlutterFire.
But as the FlutterFire background push notifications handler run on an isolate, we don't know where to find a valid BuildContext.

I have the same issue but for me, I fixed it by defining a global variable like below:
BuildContext globalContext;
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
print("Handling a background message: ${message.data}");
Provider.of<HomePageSearchFlag>(globalContext, listen: false)
.changeStatus(searchStatus: true);
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
void initState() {
// TODO: implement initState
super.initState();
globalContext = context;
Future.delayed(Duration.zero, () {
setupFCM(context);
});
}
}

Related

Flutter Lifecycle: How to correctly use dispose()?

I'm new to flutter and currently have a very basic app where I've managed to implement the Application Life cycle Management. If the app has been closed it returns AppLifecycleState.inactive then AppLifecycleState.paused then when I open it up again it returns AppLifecycleState.resume, Which all works fine. My issue is I want the life cycle to only work on one of my pages, when I navigate to a second page I want the life cycle to stop.
How can I use the dispose() on my second page to stop the life cycle?
I was thinking about importing my first file into my second file then calling the dispose(), but would that work?
I know the dispose() is used to end the life cycle which I can trigger if its on the file but I would like to trigger it within another file.
Is what im asking evening possible or am I thinking about this the wrong way?
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
#override
void initState() {
WidgetsBinding.instance.addObserver(this);
super.initState();
}
#override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Tutorial Lifecycle'),
),
body: Center(),
);
}
}
Try making new separated service for lifecycle like this.
class MyLibrary with WidgetsBindingObserver {
AppLifecycleState? _state;
AppLifecycleState? get state => _state;
MyLibrary() {
WidgetsBinding.instance!.addObserver(this);
}
/// make sure the clients of this library invoke the dispose method
/// so that the observer can be unregistered
void dispose() {
WidgetsBinding.instance!.removeObserver(this);
}
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
this._state = state;
}
void someFunctionality() {
// your library feature
}
}
Now you can dispose life cycle at any page by using
MyLibrary().dispose();

Error Im getting is - Null Function(DataSnapshot) can;t be assigned to the parameter type 'FutureOr<dynamic> Function(DatabaseEvent)'

Error Im getting is - Null Function(DataSnapshot) can;t be assigned to the parameter type 'FutureOr Function(DatabaseEvent)'Im trying to retrieve data from firebase but it is not happening.
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final textcontroller = TextEditingController();
final databaseRef = FirebaseDatabase.instance.reference();
final Future<FirebaseApp> _future = Firebase.initializeApp();
//FirebaseAuth auth = FirebaseAuth.instance;
void addData(String data) {
databaseRef.child("Valve").set({Flow : 'ON'});
}
void addData2(String data) {
databaseRef.child("Valve").set({Flow : 'OFF'});
}
void ReadData_once() {
databaseRef.child("FirebaseIOT").child("LatestReading").once().then((DataSnapshot Snapshot) {
print();
});//this is the error
}
void printFirebase(){
databaseRef.once().then((DataSnapshotsnapshot) {
print('Data : ');
});
}//this is where error is coming
Instead of DataSnapshot, you should put DatabaseEvent within the then
So this part
databaseRef.child("FirebaseIOT").child("LatestReading").once().then((DataSnapshot Snapshot) {print('test')}
should be
databaseRef.child("FirebaseIOT").child("LatestReading").once().then((DatabaseEvent event) {print('test')}
I am not a dart/flutter programmer but i know that you have to initialize app before any other modules you want to use from firebase library.
So try to switch this lines:
final Future<FirebaseApp> _future = Firebase.initializeApp();
final databaseRef = FirebaseDatabase.instance.reference();
And i'm pretty sure initializeApp() needs firebase config object so you should initialize like this: firebase.initializeApp(firebaseConfig).
I don't know what is this: Future<FirebaseApp> why you force to get initialization result to be this future generic object ?

unable to pass data to a different class

My main class MainScreenState has a function saveRideRequest that saves a node to firebase where I need to get a key from, I need to pass this key to another class TipTop but every time my code runs the value sent and obtained is null. How can I fix it ? In short, I want to pass rideRequestRef.key from mainScreen to class TipTop as rideReqKey
class MainScreen extends StatefulWidget {
const MainScreen({Key key}) : super(key: key);
#override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
DatabaseReference rideRequestRef;
void saveRideRequest() {
rideRequestRef =
FirebaseDatabase.instance.reference().child("Ride Requests").push();
///some code
print (rideRequestRef.key); //gets correct value
}
#override
Widget build(BuildContext context) {
return Container(child: TipTop(
saveRiderAndSearchNearRidecallback: (rideReqKey, listDriver) async {
saveRideRequest();
rideReqKey = rideRequestRef.key;
}));
}
}
class TipTop extends StatefulWidget {
final Function(String, List) saveRiderAndSearchNearRidecallback;
const TipTop({Key key, this.saveRiderAndSearchNearRidecallback})
: super(key: key);
#override
State<StatefulWidget> createState() => _StateTipTop();
}
class _StateTipTop extends State<TipTop> {
#override
Widget build(BuildContext context) {
return Container(child: GestureDetector(
onTap: () {
String rideReqKey;
List tempList;
widget.saveRiderAndSearchNearRidecallback(rideReqKey, tempList);
print(rideReqKey); //Null here
},
));
}
}
Try this:
class MainScreen extends StatefulWidget {
const MainScreen({Key key}) : super(key: key);
#override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
DatabaseReference rideRequestRef;
void saveRideRequest() {
rideRequestRef =
FirebaseDatabase.instance.reference().child("Ride Requests").push();
///some code
print (rideRequestRef.key); //gets correct value
}
#override
Widget build(BuildContext context) {
return Container(child: TipTop(
saveRiderAndSearchNearRidecallback: (rideReqKey, listDriver) async {
saveRideRequest();
rideReqKey = rideRequestRef.key;
},
rideReqKey:rideRequestRef.key
));
}
}
class TipTop extends StatefulWidget {
final String rideReqKey;
final Function(String, List) saveRiderAndSearchNearRidecallback;
const TipTop({Key key, this.saveRiderAndSearchNearRidecallback, this. rideReqKey})
: super(key: key);
#override
State<StatefulWidget> createState() => _StateTipTop();
}
class _StateTipTop extends State<TipTop> {
#override
Widget build(BuildContext context) {
return Container(child: GestureDetector(
onTap: () {
List tempList;
widget.saveRiderAndSearchNearRidecallback(rideReqKey, tempList);
print(rideReqKey); //No longer null.
},
));
}
}

calculate discount of prices in flutter

I want to try define below formula to calculate between old price and new price and show it on text widget but when i want to use it in an double variable i've got this error : "Only static members can be accessed in initializers"
and this is what i want to do:
class ProductDetails extends StatefulWidget {
final prod_fullName;
final prod_pic;
final prod_old_price;
final prod_price;
double percent=(prod_old_price - prod_price)/prod_old_price*100;
ProductDetails({
this.prod_fullName,
this.prod_pic,
this.prod_old_price,
this.prod_price,
});
#override
_ProductDetailsState createState() => _ProductDetailsState();
}
class _ProductDetailsState extends State<ProductDetails> {
Row{
child:new Text("$percent%");
}
class ProductDetails extends StatefulWidget {
final String prod_fullName;
final String prod_pic;
final double prod_old_price;
final double prod_price;
const ProductDetails({Key key, this.prod_fullName, this.prod_pic, this.prod_old_price, this.prod_price}) : super(key: key);
#override
_ProductDetailsState createState() => _ProductDetailsState();
}
class _ProductDetailsState extends State<ProductDetails> {
double percent;
#override
void initState() {
percent=(widget.prod_old_price - widget.prod_price)/widget.prod_old_price*100;
super.initState();
}
#override
Widget build(BuildContext context) {
return Text("$percent%");
}
}

The listener runs again every time the widget rebuild

i want to listen if there is a constant change in my firestore db. But it runs when widget rebuild (idk
because of init state? but why listener dont prevent the fonc?)
class _ActivityScreen extends State<ActivityScreen> {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
#override
void initState(){
super.initState();
checkFocChanges();
}
checkFocChanges() async {
var reference = Firestore.instance.collection('etkinlikler').orderBy('sıra');
reference.snapshots().listen((querySnapshot) {
querySnapshot.documentChanges.forEach((change) {
resetDb(change.document.data);
});
});
}
void resetDb(documents){
print(documents['ad'].toString());}
#override
Widget build(BuildContext context) {
return BlocProvider(
builder:(BuildContext context ) => ActivitiesBloc(),
I really need help between the firestore and the flutter.

Resources