Firebase functions callable "isn't referenced" when used in Flutter

I've deployed a HTTPS function on firebase and I try to call it from my Flutter app, but nothing happens.

I got the following error in my code:

The declaration 'paymentRequest' isn't referenced. Try removing the declaration of 'paymentRequest'.

Here is my successfully deployed function in Firebase:

// Generate Payment URL
exports.paymentRequest = functions.https.onCall(async (data, context) => {
    const clientAccessToken = data.clientAccessToken;
    const recipientIban = data.recipientIban;
    const recipientName = data.recipientName;
    const paymentDescription = data.paymentDescription;
    const paymentReference = data.paymentReference;
    const productPrice = parseInt(data.productPrice);

    const jsonData = {
        "destinations": [
                {
                    "accountNumber": recipientIban,
                    "type": "iban"          
                }
            ],
            "amount": productPrice,
            "currency": "EUR",
            "market": "FR",
            "recipientName": recipientName,
            "sourceMessage": paymentDescription,
            "remittanceInformation": {
                "type": "UNSTRUCTURED",
                "value": paymentReference
                },
            "paymentScheme": "SEPA_INSTANT_CREDIT_TRANSFER"
    };
    
    axios({
        method: "post",
        url: "https://myapiendpoint.com/api/v1/requests",
        headers: { 
            'Content-Type': 'application/json',
            Accept: 'application/json',
            Authorization: `Bearer ${clientAccessToken}`,},
        data: jsonData,
        })
        .then(function (response) {
            //handle success
            console.log(response.data);
        })
        .catch(function (response) {
            //handle error
            console.log(response);
        });

        return response.data;
})

And here is an extract of my flutter code:

import 'package:cloud_functions/cloud_functions.dart';
...visual stuff...
child: ElevatedButton(
                    child: const Text('Submit'),
                    onPressed: () {
                      Future<void> paymentRequest(String message) async { // This is where I have an error
                        HttpsCallable callable = FirebaseFunctions.instance
                            .httpsCallable('paymentRequest');
                        final resp = await callable.call(
                          <String, dynamic>{
                            'clientAccessToken':
                                'a_valid_token',
                            'recipientIban': ibanController,
                            'recipientName': nameController,
                            'paymentDescription': descriptionController,
                            'paymentReference': referenceController,
                            'productPrice': productPriceController
                          },
                        );
                        print("result: ${resp.data}");
                      }

                      showDialog(
                        context: context,
                        builder: (context) {
                          return AlertDialog(
                            // Retrieve the text the that user has entered by using the
                            // TextEditingController.
                            title: Text('Success!'),
                            // content: Text(productPriceController.text),
                            content: Text(
                                'The product page has been successfully updated.'),
                            actions: [
                              Center(
                                child: ElevatedButton(
                                  style: ElevatedButton.styleFrom(),
                                  onPressed: () async {
                                    // Navigator.pushReplacementNamed(
                                    //     context, '/');
                                    Navigator.of(context).push(
                                        MaterialPageRoute(
                                            builder: (context) => HomeScreen(
                                                productPrice:
                                                    productPriceController
                                                        .text)));
                                  },
                                  child: Text('Go to Product page'),
                                ),
                              ),
                            ],
                          );
                        },
                      );
                    },
                  )

Any ideas?

Thanks!


Solution 1:

Instead of declaring a new function inside a callback

onTap: () {
  Future<void> someFunctionDeclaration() async {
    // your cloud functions call and consequent showDialog
  }
}

just create a seperate function inside the widget (or other file)

class X extends StatelessWidget {

  ...

  @override 
  Widget build(BuildContext context) {
    return Widget(
    // visual stuff

        ElevatedButton(
          onTap: () async {
            await someFunction(messageVariable);
            showDialog...
          }
        ),
    // more visual stuff
    // end of build method
  }

  Future<void> someFunction(String message) async {
    HttpsCallable callable = FirebaseFunctions.instance.httpsCallable('paymentRequest');
    final resp = await callable.call(
      <String, dynamic>{
        'clientAccessToken': 'a_valid_token',
        'recipientIban': ibanController,
        'recipientName': nameController,
        'paymentDescription': descriptionController,
        'paymentReference': referenceController,
        'productPrice': productPriceController
      },
    );
  }
}

This also has the advantage of making your code cleaner. It's easier to read something like processPayment(data) than a whole segment of business logic in the view code.