0
votes

I am trying to update some values that I will enter from my Flutter app to FireStore using Cloud Functions. Here is my code so far:

This is my Cloud function (in JavaScript, index.js) to update a document in FireStore:

exports.update = functions.https.onRequest((req, res) => {
const getNewPercentage = req.body;
const getDocument = admin.firestore().collection('waterpercentage').doc('percentage');

getDocument.get().then((doc) => {
    if(doc.exists) {
        getDocument.update({'percentage': getNewPercentage}).catch(err => {
            console.log("Error: ", err);
            res.send("500");
        })
    }
}).catch(err => {
    console.log("Error: ", err)
    res.send("500");
});
res.send(200);

})

In Flutter, here's what I tried:

  Future<void> updateWaterPercentage() async {
HttpsCallable callable = FirebaseFunctions.instance.httpsCallable('update');
//final results = await callable.call(<dynamic, int>{'percentage' : percentage.round()});
log("Calling percentage here: ");
log(percentage.round().toString());
dynamic resp = await callable.call(<double, dynamic> {
  percentage : percentage.round(),
});

When I call updateWaterPercentage() from a Button in Flutter, the data doesn't get updated in FireStore. I also tried using:

CloudFunctions.instance.call(
                    functionName: "update",
                    parameters: {
                      "percentage": percentage.round(),
                    }
                  );

However, even though I imported 'package:cloud_functions/cloud_functions.dart'; on top, Flutter doesn't recognize CloudFunctions. How can I get the code to call update that takes in a parameter to correctly update a value in Firestore?

1

1 Answers

0
votes

You are mixing Callable Cloud Functions and HTTPS Cloud Functions.

Your Cloud Function code corresponds to an HTTP one (functions.https.onRequest((req, res) => {(...)}) but the code in your app declares and calls a Callable one (HttpsCallable callable = FirebaseFunctions.instance.httpsCallable('update');).

In addition, in your HTTPS Cloud Function code, you send back a response before the asynchronous operation is complete (see the last line res.send(200);).

You should adapt one or the other, most probably adapt your Cloud Function to be a Callable one (to get the advantages of a Callable, including the use of the cloud_functions package which makes very easy to call the CF from your app). Something along the following lines:

exports.update = functions.https.onCall((data, context) => {
    const getNewPercentage = data.percentage;

    const documentRef = admin.firestore().collection('waterpercentage').doc('percentage');

    return documentRef.get()
        .then((doc) => {
            if (doc.exists) {
                return getDocument.update({ 'percentage': getNewPercentage });
            } else {
                throw new Error('Doc does not exist');
            }
        })
        .then(() => {
            return { result: "doc updated" };
        })
        .catch(err => {
            console.log("Error: ", err)
            // See the doc: https://firebase.google.com/docs/functions/callable#handle_errors
        });

});