Zeusox
Zeusox

Reputation: 8448

Flutter : Save to Firestore

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

Answers (2)

emerssso
emerssso

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 onTaps 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

vbandrade
vbandrade

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

Related Questions