firebase-tools: 7.30
Plateforme : macOS 10.14.6
Mon objectif est de faire en sorte que les demandes d'émulateur Firestore authentifiées fonctionnent localement dans un navigateur. Le cas d'utilisation spécifique est pour les tests locaux. Pour tester ce cas, j'ai cloné le référentiel firebase/quickstart-nodejs et ajouté un simple jeton d'authentification fictif à l'exemple firestore-emulator/browser-quickstart
comme décrit dans https://github.com/firebase/firebase-tools/issues/ 1001#issuecomment -523319483.
Consultez la branche webchannel-auth-issue pour un cas de test minimal démontrant le problème (les modifications sont contenues dans https://github.com/jkeys089/quickstart-nodejs/commit/a1456011525b0d40e5af14b38ca26898c6199151).
Exécutez l'exemple firestore-emulator/browser-quickstart normalement.
L'exemple de projet devrait fonctionner normalement (c'est-à-dire permettre à l'utilisateur de saisir du texte dans la zone de texte, de le stocker dans l'émulateur Firestore local, puis de voir le texte affiché avec succès au-dessus de la zone de texte).
Lors de l'exécution de l'exemple de projet, nous voyons plusieurs erreurs dans la console de développement du navigateur lors du chargement de la page ( Uncaught Error in onSnapshot: FirebaseError:
) et lors de la tentative de publication de texte ( Uncaught (in promise) FirebaseError: PERMISSION_DENIED:
).
En fait, j'ai passé du temps à déboguer ce problème et je pense avoir découvert le problème. Bien que la source de l' émulateur Firestore ne soit pas disponible, j'ai réussi à créer un correctif qui corrige ce bogue / permet aux requêtes authentifiées de fonctionner comme prévu :
--- 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 Je vous récompense 100 points Internet pour avoir fourni un correctif à un émulateur non open source ! Merci d'avoir rendu cela très clair.
@ryanpbrewster ou @IanWyszynski qu'en pensez-vous ?
Travail impressionnant :)
Pour ce que ça vaut, c'est très similaire au code qui a été réellement ajouté pour gérer ce cas. Si vous effectuez une mise à niveau vers la version 1.8.1 de l'émulateur Firestore (fourni avec la version 7.3.0 du package firebase-tools
), cela devrait être corrigé.
Veuillez rouvrir ce problème si vous rencontrez d'autres problèmes, et merci encore pour le rapport ! :sourire:
Commentaire le plus utile
@jkeys089 Je vous récompense 100 points Internet pour avoir fourni un correctif à un émulateur non open source ! Merci d'avoir rendu cela très clair.
@ryanpbrewster ou @IanWyszynski qu'en pensez-vous ?