Search code examples
androidfirebasegoogle-cloud-functionsrecaptcha

Google Firebase Cloud Functions: Android app's call to backend which calls `siteverify` actually requires a billing account to be used


I use Google Firebase Cloud Functions to host the following script to check whether the ReCaptcha typed the user of my Android app is correct or not. The idea is that after the user types the captcha, the app calls the Cloud Functions' script (hosted in Google servers). The latter then calls itself the following URL with a POST request: https://www.google.com/recaptcha/api/siteverify.

Problem: in the Google servers' logs, I've found the following error:

Billing account not configured. External network is not accessible and quotas are severely limited. Configure billing account to remove these restrictions

Error: Error: getaddrinfo EAI_AGAIN www.google.com:443
    at Request._callback (/srv/index.js:20:10)
    at self.callback (/srv/node_modules/request/request.js:185:22)
    at emitOne (events.js:116:13)
    at Request.emit (events.js:211:7)
    at Request.onRequestError (/srv/node_modules/request/request.js:881:8)
    at emitOne (events.js:116:13)
    at ClientRequest.emit (events.js:211:7)
    at TLSSocket.socketErrorListener (_http_client.js:401:9)
    at emitOne (events.js:116:13)
    at TLSSocket.emit (events.js:211:7)

The backend script, hosted in Google Cloud Functions' servers, is the following:

const functions = require('firebase-functions');
const request2 = require('request');

/**
 * Verifies a Recaptcha filled by the user in his Android app.
 * 1. Success: returns the JSON response
 * 2. Failure: throws the error
 **/
exports.verifyRecaptcha = functions.https.onRequest((request, response) => {

    const user_response_token = request.query.user_response_token;
    if(user_response_token === '') {
        throw new functions.https.HttpsError('invalid-argument', 'The function must be called with an adequat user response token.');
    }

    const remote_url = 'https://www.google.com/recaptcha/api/siteverify';
    const secret = '';
    request2.post({url: remote_url, form:{secret: secret, response: user_response_token}}, function(error, response, body) {
        if(error) {
            throw new functions.https.HttpsError('unknown', error);
        }

        if(!response.statusCode !== 200) {
            throw new functions.https.HttpsError('unknown', 'Something went wrong. Status code: ' + response.statusCode + '.');
        }

        if(!body.success) {
            throw new functions.https.HttpsError('unknown', 'Unable to verify this captcha.');
        }

        return response;
    });

});

My question is: Is there any way to request this URL without having to create a billing account?


Solution

  • Edit: As Frank points out in the comments, I missed that this was an internal URL, and the message is always displayed for the free plan, even though the requests should work. If the request isn't working, then a bug should be filed.

    My answer was for a non-Google (e.g. external) URL, which I'll leave in place below (as it will allow you to bypass the check while the bug is resolved).


    No. You need a billing account to make external network requests from Cloud Functions. See the Cloud Functions Section of the pricing page.

    Just configuring a billing account however still allows you to take advantage of the free tier limits of the Spark plan. There is no actual cost incurred just for making an external network request.