Firebase-tools: Firestore emulator WebChannel auth not honored

Created on 28 Aug 2019  ·  3Comments  ·  Source: firebase/firebase-tools

Environment info

firebase-tools: 7.30

Platform: macOS 10.14.6

Test case

My goal is to get authenticated firestore emulator requests working locally in a browser. The specific use case is for local testing. To test this case I've cloned the firebase/quickstart-nodejs repo and added a simple mock auth token to the firestore-emulator/browser-quickstart sample as described in https://github.com/firebase/firebase-tools/issues/1001#issuecomment-523319483.

See the webchannel-auth-issue branch for a minimal test case demonstrating the issue (changes are contained in https://github.com/jkeys089/quickstart-nodejs/commit/a1456011525b0d40e5af14b38ca26898c6199151).

Steps to reproduce

Run the firestore-emulator/browser-quickstart sample as normal.

Expected behavior

The sample project should work as normal (i.e. allow the user to enter text in the textarea, store it in the local firestore emulator, and then see the text successfully shown above the textarea).

Actual behavior

When running the sample project we see multiple errors in the browser development console when loading the page (Uncaught Error in onSnapshot: FirebaseError:) and when attempting to post text (Uncaught (in promise) FirebaseError: PERMISSION_DENIED:).

emulator-suite firestore bug

Most helpful comment

@jkeys089 I award you 100 internet points for providing a patch to a non-open source emulator! Thank you for making this really clear.

@ryanpbrewster or @IanWyszynski what do you think?

All 3 comments

I actually spent some time debugging this issue and I believe I've discovered the issue. Although the source for the firestore emulator is not available I did manage to create a patch which fixes this bug / allows authenticated requests to function as expected:

--- com/google/cloud/datastore/emulator/firestore/webchannel/FirestoreV1WebChannelAdapter.java    2019-08-28 00:42:06.000000000 -0400
+++ FirestoreV1WebChannelAdapter.java    2019-08-27 23:34:54.000000000 -0400
@@ -190,7 +190,17 @@
          String url = channel.getHandshakeHeaders().getUrl();
          QueryStringDecoder decoder = new QueryStringDecoder(url);
          String db = (String)((List)Preconditions.checkNotNull((List)decoder.parameters().get("database"), "expected %s to have a 'database' query parameter", (Object)url)).get(0);
-         Context.current().withValue(FirestoreEmulatorMetadataKeys.DATABASE_REF.contextKey(), db).run(() -> {
+         String auth = null;
+         if (decoder.parameters().get("$httpHeaders") != null) {
+            for (String rawHeader : decoder.parameters().get("$httpHeaders").get(0).split("\r\n")) {
+               if (rawHeader.startsWith("Authorization:")) {
+                  auth = rawHeader.substring(14).trim();
+                  break;
+               }
+            }
+         }
+         Context.current().withValue(FirestoreEmulatorMetadataKeys.AUTHORIZATION.contextKey(), auth).withValue(
+            FirestoreEmulatorMetadataKeys.DATABASE_REF.contextKey(), db).run(() -> {
             Object handler;
             if (url.startsWith("/google.firestore.v1.Firestore/Write/")) {
                handler = new FirestoreV1WebChannelAdapter.FirestoreWriteHandler(this.router, channel);

@jkeys089 I award you 100 internet points for providing a patch to a non-open source emulator! Thank you for making this really clear.

@ryanpbrewster or @IanWyszynski what do you think?

Impressive work :)

For what it's worth, that's very similar to the code that was actually added to handle this case. If you upgrade to v1.8.1 of the Firestore emulator (which shipped with v7.3.0 of the firebase-tools package) this should be fixed.

Please re-open this issue if you encounter any other problems, and thanks again for the report! :grinning:

Was this page helpful?
0 / 5 - 0 ratings