35

Surprisingly-even more when both are Google products-there is no information that I can find on how to integrate Recaptcha with Firebase. Is it even possible? If not, what can I use to validate humans on a Firebase app that has no auth?

4
  • I'm currently looking into this too. Will come back with an answer or update when I have something. Apr 14, 2017 at 15:01
  • I haven't started on my solution yet, however, I'm looking to use Cloud Functions for Firebase to firebase.google.com/docs/functions to integrate with Recaptcha. There are similar use cases here: github.com/firebase/functions-samples Apr 15, 2017 at 14:38
  • I don't know if I am too late. Now there is Firebase's Cloud Function. You can write your own backend API in javascript on it. Instead of calling firebase database right out of the client, you call your custom API via Firebase's Cloud Function on the client and authenticate the reCaptcha there and do something with your database as an admin (firebase-admin). I tried it and it works fine.
    – pupuupup
    Apr 26, 2017 at 4:45
  • 1
    This is the flow on what I did.. 1) authenticate that client is not robot using reCaptcha 2) send the token with post data to custom cloud function API 3) the reCaptcha token will be authenticated in the cloud function 4) update the data in firebase database as an admin. (the security rule can be .write: false, the cloud function will be able to write on it as a "firebase-admin", only client that passes through reCaptcha authentication will be able to write on it)
    – pupuupup
    Apr 26, 2017 at 4:49

2 Answers 2

27

This is a pretty old post, but here's the answer for fellow Google searchers like me. It's now built-in, and super easy to set up:

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha', {
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
})
window.recaptchaVerifier.render()

As tuananh mentions, make sure you add a <div id="recaptcha"></div>.

3
  • 1
    To void exception "Error: reCAPTCHA container is either not found or already contains inner elements". Please add element with id="recaptcha", ex: <div id="recaptcha"></div>
    – tuananh
    Jan 22, 2018 at 4:20
  • 3
    I just want to note that this method uses "firebase.auth" which is not valid for server-side authentication or node.js implementation. It's only "built-in" for client-side javascript projects. The method above by Doug Stevenson is necessary for anyone doing server-side rendering. For example, if you want firebase functions to verify a captcha before sending the user's input over to another function to create a new user account using the admin SDK. Jan 27, 2018 at 0:21
  • 1
    I can't find how to make this work with signInWithEmailAndPassword, it doenst have a third parameter waiting for the appVerifier, as the signInWithPhoneNumber does
    – leoxs
    Nov 20, 2019 at 17:39
11

I've just published a tutorial blog on how to integrate reCAPTCHA in a web site using Firebase Hosting to serve content and Cloud Functions for Firebase to validate the response received from the reCAPTCHA. The function itself looks like this, assuming that the response token is received through the query string:

const functions = require('firebase-functions')
const rp = require('request-promise')

exports.checkRecaptcha = functions.https.onRequest((req, res) => {
    const response = req.query.response
    console.log("recaptcha response", response)
    rp({
        uri: 'https://recaptcha.google.com/recaptcha/api/siteverify',
        method: 'POST',
        formData: {
            secret: 'PASTE_YOUR_SECRET_CODE_HERE',
            response: response
        },
        json: true
    }).then(result => {
        console.log("recaptcha result", result)
        if (result.success) {
            res.send("You're good to go, human.")
        }
        else {
            res.send("Recaptcha verification failed. Are you a robot?")
        }
    }).catch(reason => {
        console.log("Recaptcha request failure", reason)
        res.send("Recaptcha request failed.")
    })
})
7
  • 1
    Are there any alternatives to using request promise. const rp = require('request-promise')?
    – Gal Bracha
    Oct 26, 2017 at 18:04
  • How about if I want to use this before I allow users to OAuth with Facebook Or Google?
    – Gal Bracha
    Oct 26, 2017 at 18:05
  • 2
    You can use whatever HTTP client library you like, as long as you follow the spec for the reCAPTCHA API. You can do it whenever you want as well. Oct 26, 2017 at 20:49
  • how would I format tan http request instead of window.location? what would that request be like?
    – SeanMC
    Aug 1, 2018 at 1:35
  • 1
    How's this supposed to work in a web app though? Coz if I put this function call before registration, say, people can just bypass it and go straight to registration, making the recaptcha call pointless. You'd have to send the email and password from the client to this function, and do the registration server-side once recaptcha has successfully passed for this to have any credibility.
    – SeriousLee
    Apr 11, 2020 at 6:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.