Reputation: 8448
I have a method called _sendToDatabaseWithArgs
that takes some arguments and save them to firestore database onTap. The arguments are already populated from the first screen that has a form and takes in 3 inputs.
The problem is when I perform an onTap action, data will not save to firestore. However, when I save the program, data automatically saves to Database !!!!
Here is the class that is supposed to handle this:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'StoreData.dart';
class FeedBack extends StatelessWidget {
final StoreData storeData;
String feedBackHolder = "";
FeedBack({Key key, @required this.storeData}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Navajo Inc Feedback"),
),
body: new Container(
padding: new EdgeInsets.all(15.0),
child: new ListView(
// crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new RaisedButton(onPressed: _sendToDatabaseWithArgs(storeData.storeNumber, storeData.repName, storeData.repCell, storeData.transactionDate),
child: const Text('RAISED BUTTON'),
),
new GestureDetector(
onTap: _sendToDatabaseWithArgs(storeData.storeNumber, storeData.repName, storeData.repCell, storeData.transactionDate),
child: feedBackCardsImage(
imagePath: 'assets/happy_face.png',
CardTitle: 'Happy Customer',
CardTag: 'Experience was excellent',
),
),
new GestureDetector(
onTap: _sendToDatabase,
child: feedBackCardsImage(
imagePath: 'assets/neutral_face.png',
CardTitle: 'Neutral Customer',
CardTag: 'Experience was satisfactory',
),
),
new GestureDetector(
onTap: _sendToDatabase,
child: feedBackCardsImage(
imagePath: 'assets/angry_face.png',
CardTitle: 'Unsatisfied Customer',
CardTag: 'Experience was unsatisfactory',
),
),
],
),
),
);
}
_sendToDatabaseWithArgs(String storeNumber,repName,repCell, DateTime transactionDate) {
Firestore.instance.runTransaction((Transaction transaction) async {
CollectionReference reference = Firestore.instance.collection('Stores');
await reference.add({
"store Name": storeNumber,
"Rep Name": repName,
"Rep Cell": repCell,
"Transaction Date": transactionDate,
});
});
}
_sendToDatabase() {
Firestore.instance.runTransaction((Transaction transaction) async {
CollectionReference reference = Firestore.instance.collection('Stores');
await reference.add({
"store Name": "${storeData.storeNumber}",
"Rep Name": "${storeData.repName}",
"Rep Cell": "${storeData.repCell}",
"Transaction Date":"${storeData.transactionDate}",
});
});
}
}
// feedback cardsImage widget / class
class feedBackCardsImage extends StatelessWidget {
final String imagePath;
final String CardTitle;
final String CardTag;
feedBackCardsImage({
this.imagePath,
this.CardTitle,
this.CardTag,
});
@override
Widget build(BuildContext context) {
return new Container(
child: new Card(
child: new Padding(
padding: new EdgeInsets.all(15.0),
child: new Column(
children: <Widget>[
new SizedBox(
height: 184.0,
child: new Stack(
children: <Widget>[
new Positioned.fill(
child: new Image.asset(
imagePath,
//package: destination.assetPackage,
fit: BoxFit.contain,
),
),
],
),
),
new Padding(padding: new EdgeInsets.all(7.0,),
child: new Text(CardTitle, style: new TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, color: Colors.black87), ),
),
new Padding(padding: new EdgeInsets.all(0.0,),
child: new Text(CardTag, style: new TextStyle(fontSize: 12.0, fontWeight: FontWeight.w400, color: Colors.black54), ),
),
],
),
),
),
);
}
}
Any insight would be appreciated !
Upvotes: 0
Views: 2572
Reputation: 2386
I think your issue is that Flutter is assigning the result of calling _sendToDatabaseWithArgs
to onTap instead of calling the method when onTap is called. That's why you see it execute _sendToDatabaseWithArgs
when the app is saved/hot-reloaded; it is calling the method when it loads up the widget.
To fix this, I would change the onTap
s to:
onTap: () => _sendToDatabaseWithArgs(...)
This way, Flutter knows to call the lambda that calls your method with the right arguments, instead of calling your method and expecting it to return a callable object that get's called when the widget is tapped.
Note that this happens when the argument of onTap
has arguments. I wouldn't expect this to be an issue for the other places where you do onTap: _sendToDatabase
, because you are giving Flutter a reference to hold onto, not an expression to evaluate (so that it can get a reference to hold).
Upvotes: 2
Reputation: 2662
How about creating a new document directly?
Future<void> _sendToDatabase() {
return Firestore.instance.runTransaction((Transaction transactionHandler) {
return Firestore.instance
.collection(_entriesPath)
.document()
.setData({
"store Name": "${storeData.storeNumber}",
"Rep Name": "${storeData.repName}",
"Rep Cell": "${storeData.repCell}",
"Transaction Date":"${storeData.transactionDate}",
});
});
}
Upvotes: 0