Ferda Nahit FIDANCI
Ferda Nahit FIDANCI

Reputation: 379

How to show "Saving" text in a button when updating a field in Firestore?

I was working on a project. And I need to achieve this functionality. I have a simple button center of screen. And it has a child of Text widget. When widget tree rebuilding it gets a document from Cloud Firestore. Meanwhile, Text widget says "loading". After it gets the document, it shows a basic number field of the document like as "Value: 0".


When I press the button, it will increment the field called value in Cloud Firestore. It is working properly.


But, I also want to show a Text widget that says Saving... when I actually updating the value.


To sum up, updating process should go like that: Value: 11 -> Pressed button -> Saving... -> Loading... -> Value: 12


How can I achieve this?


What I did so far?

Future<String> getData() async {
  var fb = Firestore.instance;

  DocumentSnapshot dr =
      (await fb.collection("records").document("the record").get());

  return dr.data["value"].toString();
}

void updateData(int value) async {
  var fb = Firestore.instance;

  await fb.collection("records").document("the record").updateData({
    "value": value + 1,
  });
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Homework 4"),
      ),
      body: Center(
          child: FutureBuilder(
              future: getData(),
              builder: (context, snapshot) {
                if (snapshot.connectionState == ConnectionState.waiting) {
                  return RaisedButton(
                    child: Text("Loading"),
                    onPressed: null,
                  );
                }

                if (snapshot.connectionState == ConnectionState.done) {
                  return RaisedButton(
                    child: Text("Value: " + snapshot.data),
                    onPressed: () {
                      setState(() {
                        updateData(int.parse(snapshot.data));
                      });
                    },
                  );
                }

                return RaisedButton(
                  child: Text("saving"),
                  onPressed: null,
                );
              })),
     
    );
  }

Upvotes: 0

Views: 200

Answers (2)

VLXU
VLXU

Reputation: 729

First, call setState and show “Loading...” before doing updateDate()

You can then use ....get().then((result){ }) (not whenComplete(); this is good practice as it ensures that only successful futures may proceed with the next step).

Inside the .then() you can set the state to show “Saving ...” and call the fetching function.

The fetch function itself can have another .then() to call setState again and show the “Value: 0”

While it might seem wise to use FutureBuilder I would say the requirement of having to show “Saving” during the update would make the solution equally as convoluted.

I was thinking that the solution involving a FutureBuilder would need some sort of flag variable to indicate that we are saving and inside the build function show a button with the Text “Saving” if the flag indicates that we are awaiting the update.

Upvotes: 1

Remon Shehatta
Remon Shehatta

Reputation: 1470

I don't know about Dart. but you can use the onCompleteListener method from Firebase. what you would do would be something like this:

  1. when the user clicks save, change the text to saving
  2. when the onCompleteListener is called you can change the text back

Upvotes: 0

Related Questions