8

How are developers working with Firebase App Check when developing locally using the emulator on localhost? Are you disabling App Check on localhost entirely? Or are you able to emulating App Check locally?

Firebase has some instructions on using App Check with a debug provider, but the use case for that seems to be when you want to debug locally but use GCP's backend services in the cloud. It doesn't look relevant for developing against the emulator.

Running this in the client fails recaptcha app attestation with a 403 response (PERMISSION_DENIED), presumably because localhost is not listed as an allowed domain:

  const appCheck = firebase.appCheck();
  appCheck.activate(
    process.env.REACT_APP_FIREBASE_APP_CHECK_SITE_KEY,
    true,
  );

When enforcing app check in callable functions, context.app is undefined when running in the emulator so requests will fail app check.

Disabling App Check locally is certainly an option, but was wondering if there was a way to emulate app check as well.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Johnny Oshika
  • 54,741
  • 40
  • 181
  • 275

1 Answers1

2

I've got it set up, but not without lots of trial and error.

Try adding this snippet right above your call to active appCheck. It seems it needs come before activating appCheck. I was getting that same error until I move the debug snippet before the active call. I am using web version 9 though... not sure if that makes a difference.

if (process.env.NODE_ENV !== 'production') {
  self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
}

const appCheck = firebase.appCheck();
appCheck.activate(
  process.env.REACT_APP_FIREBASE_APP_CHECK_SITE_KEY,
  true,
);

This will print a token to the console which will need to be added to you Firebase project settings. Like described in the link you provided.

Did you do those 2 steps and still get the 403 response?

Brian Kiernan
  • 781
  • 1
  • 5
  • 5
  • Just to confirm, are you using this when you're testing with the Firebase Emulator backend? In other words, the Emulator is verifying that app check token for things like callable functions? I thought `self.FIREBASE_APPCHECK_DEBUG_TOKEN` was for when you wanted to test your client locally while using the backend in GCP's cloud. – Johnny Oshika Nov 27 '21 at 05:54
  • Hmmm... that may be true about the token. I'm using an Express App on Cloud Run for my backend and have app check working on my server and clients using emulators for all while developing locally. I've not set app check up for a callable function on the emulators. I saw this which I'll share in case you didn't come across it yet https://firebase.google.com/docs/app-check/cloud-functions It looks like once you have appcheck configured on your client (not getting the 403) the token should show up on the context object of the callable function on the backend. It should work with the emulators too – Brian Kiernan Nov 28 '21 at 15:49
  • I do get your point though about it not seeming like its needed for your use case. If everything is running locally why would the debug token be needed? I'm still learning all the in and outs of appCheck and it seems like a great feature. I'm wondering if it could replace my need for using CSRF. It seems like appCheck is doing the same thing and more. – Brian Kiernan Nov 28 '21 at 16:02
  • @BrianKernan With App Check in place, I don't think CSRF is possible anymore by a malicious site, as there shouldn't be a way for that malicious site to construct the app check token to send with malicious requests. As for the debug token, I haven't had a chance to check whether the emulator will validate the token generated. It would be strange to register the token in project settings in the cloud, as the emulator shouldn't talk to the cloud to validate such things. As for your link in your comment, it's the same one that I included in my original question . – Johnny Oshika Nov 28 '21 at 23:06
  • 1
    @JohnnyOshika did you find a solution for the problem of emulator functions failing when `context.app` is undefined? this is driving me up the wall. – Liam Nov 29 '21 at 18:51
  • 1
    never mind, just found out about the `FUNCTIONS_EMULATOR` environment variable which is `true` when a function is running on the emulator. so `if (!context.app) { }` becomes `if(!context.app && !process.env.FUNCTIONS_EMULATOR) { }`. – Liam Nov 29 '21 at 19:03
  • @JohnnyOshika thanks Johnny... that was my thought about not needing to use CSRF and app check. Also, I realized I gave you the pretty same information from your original post after I posted my reply... sorry about that. – Brian Kiernan Nov 30 '21 at 15:30
  • @Liam I'm pretty much doing the same thing, although I wrapped the App Check in a middleware so that I'm not repeating it on every callable function. I documented how to do that here: https://stackoverflow.com/a/70057694/188740 – Johnny Oshika Nov 30 '21 at 16:01
  • @JohnnyOshika did you find a way to test with Firebase Emulator? I am facing the exact issue and not sure how to do local development with App Check. Thanks for any direction to make it work. – Cupid Chan Jun 03 '23 at 20:51
  • @CupidChan I'm ignoring AppCheck when running locally against a middleware. I haven't found a better solution. Have you? – Johnny Oshika Jul 09 '23 at 05:28
  • @JohnnyOshika I only disable the AppCheck when I use an emulator. – Cupid Chan Jul 10 '23 at 21:20