инструменты firebase: 7.30
Платформа: macOS 10.14.6
Моя цель - заставить аутентифицированные запросы эмулятора firestore работать локально в браузере. Конкретный вариант использования - для локального тестирования. Чтобы проверить этот случай, я клонировал репозиторий firebase / quickstart-nodejs и добавил простой фиктивный токен аутентификации в образец firestore-emulator/browser-quickstart
как описано в https://github.com/firebase/firebase-tools/issues/ 1001 # issuecomment -523319483.
См. Ветку webchannel-auth-issue для минимального тестового примера, демонстрирующего проблему (изменения содержатся в https://github.com/jkeys089/quickstart-nodejs/commit/a1456011525b0d40e5af14b38ca26898c6199151).
Запустите образец firestore-emulator / browser-quickstart как обычно.
Образец проекта должен работать как обычно (т. Е. Позволять пользователю вводить текст в текстовое поле, сохранять его в локальном эмуляторе firestore, а затем видеть текст, успешно отображаемый над текстовым полем).
При запуске демонстрационного проекта мы видим несколько ошибок в консоли разработки браузера при загрузке страницы ( Uncaught Error in onSnapshot: FirebaseError:
) и при попытке опубликовать текст ( Uncaught (in promise) FirebaseError: PERMISSION_DENIED:
).
На самом деле я потратил некоторое время на отладку этой проблемы и считаю, что обнаружил проблему. Хотя источник эмулятора firestore недоступен, мне удалось создать патч, который исправляет эту ошибку / позволяет аутентифицированным запросам функционировать должным образом:
--- 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 Я награждаю вас 100 интернет-очками за предоставление патча для эмулятора без открытого исходного кода! Спасибо, что разъяснили это по-настоящему.
@ryanpbrewster или @IanWyszynski, что вы думаете?
Впечатляющая работа :)
Как бы то ни было, это очень похоже на код, который был добавлен для обработки этого случая. Если вы обновите эмулятор Firestore до v1.8.1 (который поставлялся с v7.3.0 пакета firebase-tools
), это должно быть исправлено.
Пожалуйста, повторно откройте эту проблему, если у вас возникнут другие проблемы, и еще раз благодарим за отчет! : ухмыляясь:
Самый полезный комментарий
@ jkeys089 Я награждаю вас 100 интернет-очками за предоставление патча для эмулятора без открытого исходного кода! Спасибо, что разъяснили это по-настоящему.
@ryanpbrewster или @IanWyszynski, что вы думаете?