flutterfire icon indicating copy to clipboard operation
flutterfire copied to clipboard

🐛 [firebase-messaging ] [web] - Error getToken when base href is not "/"

Open Donk3ys opened this issue 4 years ago • 23 comments

Bug report

If i change the base href from <base href="/"> in web/index.html to <base href="/admin/"> I get an error when running FirebaseMessaging.instance.getToken();

Therefore I cant have push notifications for regular website & admin website if they on the same server.

Steps to reproduce

Change the base href from <base href="/"> in web/index.html to <base href="/admin/">

When accepting the notification permissions and my code runs:

void main() async {
    runApp(MyApp());    
    FirebaseMessaging.instance.getToken().then((token) => print(token));
}

I get an error: Error: [firebase_messaging/failed-service-worker-registration] Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker for scope ('http://localhost:58007/firebase-cloud-messaging-push-scope') with script ('http://localhost:58007/firebase-messaging-sw.js'): A bad HTTP response code (404) was received when fetching the script.

Expected behavior

Print a token from FirebaseMessaging.instance.getToken();

Sample project

index.html

<!DOCTYPE html>
<html>
  <head>
    
  <!--  <base href="/"> WORKS -->
    <base href="/admin/"> <!-- DOESNT WORK -->
  
    <meta charset="UTF-8">
    <meta content="IE=Edge" http-equiv="X-UA-Compatible">
    <meta name="description" content="fcm">
  
    <!-- iOS meta tags & icons -->
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-title" content="fcm">
  
    <!-- Favicon -->
    <link rel="icon" type="icon/jpg" href="assets/logo-600.jpg"/>
  
    <title>fcm</title>
    <link rel="manifest" href="manifest.json">
  </head>
  <body>
    <script>
      if ('serviceWorker' in navigator) {
        window.addEventListener('flutter-first-frame', function () {
          //navigator.serviceWorker.register('flutter_service_worker.js');
          navigator.serviceWorker.register('firebase-messaging-sw.js');
        });
      }
    </script>
  
    <script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-messaging.js"></script>
    <script>
      var firebaseConfig = {
        apiKey: "xxx",
        authDomain: "xxx.firebaseapp.com",
        projectId: "xxx",
        storageBucket: "xxx.appspot.com",
        messagingSenderId: "xxx",
        appId: "xxx"
      };
  
      firebase.initializeApp(firebaseConfig);
    </script>
  
    <script src="main.dart.js" type="application/javascript"></script>
  </body>
</html>

firebase-messaging-sw.js

importScripts("https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js");
importScripts("https://www.gstatic.com/firebasejs/8.6.1/firebase-messaging.js");

firebase.initializeApp({
  apiKey: "xxx",
        authDomain: "xxx.firebaseapp.com",
        projectId: "xxx",
        storageBucket: "xxx.appspot.com",
        messagingSenderId: "xxx",
        appId: "xxx"
});

const messaging = firebase.messaging();

// Optional:
messaging.onBackgroundMessage((m) => {
  console.log("onBackgroundMessage", m);
});

main.dart

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';

void main() async {
  runApp(MyApp());
  FirebaseMessaging.instance.getToken().then((token) => print(token));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(),
    );
  }
}


Flutter doctor

Click To Expand
❯ flutter doctor -v
[✓] Flutter (Channel stable, 2.0.6, on macOS 11.3 20E232 darwin-x64, locale en-US)
    • Flutter version 2.0.6 at /Users/donk3y/development/flutter
    • Framework revision 1d9032c7e1 (3 weeks ago), 2021-04-29 17:37:58 -0700
    • Engine revision 05e680e202
    • Dart version 2.12.3

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    • Android SDK at /Users/donk3y/Library/Android/sdk
    • Platform android-30, build-tools 30.0.3
    • ANDROID_HOME = /Users/donk3y/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.4, Build version 12D4e
    • CocoaPods version 1.10.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-x64     • macOS 11.3 20E232 darwin-x64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 90.0.4430.212

• No issues found!


Flutter dependencies

Click To Expand
❯ flutter pub deps -- --style=compact
Dart SDK 2.12.3
Flutter SDK 2.0.6
test_firebase_message 1.0.0+1

dependencies:
- cupertino_icons 1.0.3
- firebase_core 1.1.1 [firebase_core_platform_interface firebase_core_web flutter meta]
- firebase_messaging 9.1.4 [firebase_core firebase_core_platform_interface firebase_messaging_platform_interface firebase_messaging_web flutter meta]
- flutter 0.0.0 [characters collection meta typed_data vector_math sky_engine]

dev dependencies:
- flutter_test 0.0.0 [flutter test_api path fake_async clock stack_trace vector_math async boolean_selector characters charcode collection matcher meta source_span stream_channel string_scanner term_glyph typed_data]

transitive dependencies:
- async 2.5.0 [collection]
- boolean_selector 2.1.0 [source_span string_scanner]
- characters 1.1.0
- charcode 1.2.0
- clock 1.1.0
- collection 1.15.0
- fake_async 1.2.0 [clock collection]
- firebase_core_platform_interface 4.0.1 [collection flutter meta plugin_platform_interface]
- firebase_core_web 1.0.3 [firebase_core_platform_interface flutter flutter_web_plugins js meta]
- firebase_messaging_platform_interface 2.1.4 [firebase_core flutter meta plugin_platform_interface]
- firebase_messaging_web 1.0.7 [firebase_core firebase_core_web firebase_messaging_platform_interface flutter flutter_web_plugins js meta]
- flutter_web_plugins 0.0.0 [flutter js characters collection meta typed_data vector_math]
- js 0.6.3
- matcher 0.12.10 [stack_trace]
- meta 1.3.0
- path 1.8.0
- plugin_platform_interface 2.0.0 [meta]
- sky_engine 0.0.99
- source_span 1.8.0 [charcode collection path term_glyph]
- stack_trace 1.10.0 [path]
- stream_channel 2.1.0 [async]
- string_scanner 1.1.0 [charcode source_span]
- term_glyph 1.2.0
- test_api 0.2.19 [async boolean_selector collection meta path source_span stack_trace stream_channel string_scanner term_glyph matcher]
- typed_data 1.3.0 [collection]
- vector_math 2.1.0


Donk3ys avatar May 18 '21 13:05 Donk3ys

@Donk3ys Thanks for the detailed report and code sample. If you open a new browser tab and run http://localhost:58007/firebase-messaging-sw.js, what does it show ? an actual file or any error ?

Usually, the 404 error A bad HTTP response code (404) was received when fetching the script. indicates that the file cannot be found at root of the origin.

darshankawar avatar May 19 '21 08:05 darshankawar

If I have <base href="/"> and go to http://localhost:58007/firebase-messaging-sw.js I get my file <WORKING>

If I have <base href="/admin/"> and go to http://localhost:58007/firebase-messaging-sw.js I get an error

If I have <base href="/admin/"> and go to http://localhost:58007/admin/firebase-messaging-sw.js I get my file <WORKING>

If I have <base href="/admin/"> and navigator.serviceWorker.register('/admin/firebase-messaging-sw.js'); I get same error message:

Error: [firebase_messaging/failed-service-worker-registration] Messaging: We are unable to register the default service 
worker. Failed to register a ServiceWorker for scope ('http://localhost:58007/firebase-cloud-messaging-push-scope') with 
script ('http://localhost:58007/firebase-messaging-sw.js'): A bad HTTP response code (404) was received when fetching the 
script.

Donk3ys avatar May 19 '21 13:05 Donk3ys

The base tag resolves all relative imports, which your service worker is. Have you tried:

navigator.serviceWorker.register('/firebase-messaging-sw.js');

or

navigator.serviceWorker.register('/admin/firebase-messaging-sw.js');

Ehesp avatar May 19 '21 14:05 Ehesp

@Ehesp

Thanks for the reply.

Yeah I've tried both and still get the exact same error for both, when trying to getToken().

Error: [firebase_messaging/failed-service-worker-registration] Messaging: We are unable to register the default service 
worker. Failed to register a ServiceWorker for scope ('http://localhost:58007/firebase-cloud-messaging-push-scope') with 
script ('http://localhost:58007/firebase-messaging-sw.js'): A bad HTTP response code (404) was received when fetching the 
script.

Donk3ys avatar May 19 '21 14:05 Donk3ys

Have you tried putting the full URL in for now? I believe that will ignore the base path then.

Ehesp avatar May 19 '21 15:05 Ehesp

Have you tried putting the full URL in for now? I believe that will ignore the base path then.

Still the same error message

Donk3ys avatar May 19 '21 16:05 Donk3ys

Using latest firebase_messaging plugin version and using latest JavaScript SDK version, I was able to replicate it on current stable version (2.2.0):

With default base href, we get the token back properly, but changing the href as mentioned, gives below error in the console:

dhs@Dhss-MacBook-Pro firebase_messaging_example % flutter run -d chrome
Launching lib/main.dart on Chrome in debug mode...
Waiting for connection from debug service on Chrome...             15.3s
This app is linked to the debug service: ws://127.0.0.1:51725/3RN-YodlhE4=/ws
Debug service listening on ws://127.0.0.1:51725/3RN-YodlhE4=/ws

💪 Running with sound null safety 💪

🔥  To hot restart changes while running, press "r" or "R".
For a more detailed help message, press "h". To quit, press "q".
Error: [firebase_messaging/failed-service-worker-registration] Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker for scope
('http://localhost:51703/firebase-cloud-messaging-push-scope') with script ('http://localhost:51703/firebase-messaging-sw.js'): A bad HTTP response code (404) was received when fetching
the script. .
    at Object.throw_ [as throw] (http://localhost:51703/admin/dart_sdk.js:5037:11)
    at http://localhost:51703/admin/packages/firebase_core/src/internals.dart.lib.js:81:63
    at _RootZone.runUnary (http://localhost:51703/admin/dart_sdk.js:37245:59)
    at _FutureListener.catchError.handleError (http://localhost:51703/admin/dart_sdk.js:32513:48)
    at handleError (http://localhost:51703/admin/dart_sdk.js:33044:51)
    at Function._propagateToListeners (http://localhost:51703/admin/dart_sdk.js:33070:17)
    at _Future.new.[_completeError] (http://localhost:51703/admin/dart_sdk.js:32920:23)
    at async._AsyncCallbackEntry.new.callback (http://localhost:51703/admin/dart_sdk.js:32956:31)
    at Object._microtaskLoop (http://localhost:51703/admin/dart_sdk.js:37497:13)
    at _startMicrotaskLoop (http://localhost:51703/admin/dart_sdk.js:37503:13)
    at http://localhost:51703/admin/dart_sdk.js:33274:9
flutter doctor -v
[✓] Flutter (Channel stable, 2.2.0, on Mac OS X 10.15.4 19E2269 darwin-x64,
    locale en-GB)
    • Flutter version 2.2.0 at /Users/dhs/documents/fluttersdk/flutter
    • Framework revision b22742018b (5 days ago), 2021-05-14 19:12:57 -0700
    • Engine revision a9d88a4d18
    • Dart version 2.13.0

[!] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.3, Build version 12C33
    ! CocoaPods 1.9.3 out of date (1.10.0 is recommended).
        CocoaPods is used to retrieve the iOS and macOS platform side's plugin
        code that responds to your plugin usage on the Dart side.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/platform-plugins
      To upgrade see
      https://guides.cocoapods.org/using/getting-started.html#installation for
      instructions.

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] VS Code (version 1.55.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.21.0

[✓] Connected device (3 available)
    • Darshan's iphone (mobile) • 21150b119064aecc249dfcfe05e259197461ce23 • ios
      • iOS 14.4.1
    • macOS (desktop)           • macos                                    •
      darwin-x64     • Mac OS X 10.15.4 19E2269 darwin-x64
    • Chrome (web)              • chrome                                   •
      web-javascript • Google Chrome 90.0.4430.212

! Doctor found issues in 1 category.


darshankawar avatar May 20 '21 08:05 darshankawar

I face the same problem. When trying to call getToken() in a dart script of the application, it tries to fetch the "firebase-messaging-sw.js" from our server with the wrong url and the same error occurs.

In the "index.html" we have set:

<base href="/server/demo/">

When starting our application, it initially is able to fetch the "firebase-messaging-sw.js" succesfully and it is able to register the service worker with the correct url e.g. http://localhost:8080/server/demo/firebase-messaging-sw.js. However, when we call getToken() in the application to save the token in a database, it tries to fetch the "firebase-messaging-sw.js" another time with an incorrect request url e.g. http://localhost:8080/firebase-messaging-sw.js. This throws an error since it is not accessible this way.

thiencapa avatar May 21 '21 14:05 thiencapa

maybe adding scope can help navigator.serviceWorker.register('/sw.js', {scope: '/admin/'})

praveeno avatar Jun 01 '21 05:06 praveeno

Same issue than everyone when base href is not "/", adding scope as suggested above is not working.

Any update on this issue? Running into the same problem. Confirmed @praveeno 's solution does not work.

lmordell avatar Oct 05 '21 21:10 lmordell

have the same issue here any workaround?

luisfelipesd avatar Oct 15 '21 18:10 luisfelipesd

Looks like in the firebase library someone has hardcoded the static path which is "root path" ( https://<example.com>/ ). Firebase has to change this hardcoded path or has to define a function in the library to change this hardcoded path.

Tapaswi846580 avatar Dec 20 '21 10:12 Tapaswi846580

Another workaround which anyone can think of is to put firebase-messaging-sw.js file in the root folder of the server which one can access the file just by writing the {hostname}/firebase-messaging-sw.js

Tapaswi846580 avatar Dec 20 '21 10:12 Tapaswi846580

Any update on the issue? The only way I could make it work was moving firebase-messaging-sw.js to the root folder.

palmsnipe avatar Feb 16 '22 03:02 palmsnipe

Any updates on this issue? I have the same problem, and I have googled for decades. I am desperate!

Kuryia avatar May 19 '22 14:05 Kuryia

Same issue here, I am using github pages for hosting, so the only file that will go next to the root is index.html and we cannot change that, the other files are moved to root/project_name/file.js, including firebase-messaging-sw.js, and again, you can't choose to put them at the root. It seems the call to "await FirebaseMessaging.instance.getToken()" is refreshing the serviceWorker() with root path and doesn't care at all about "base href" like Tapas explained, so I am completely stuck here :(

Novskilol avatar Jun 15 '22 15:06 Novskilol

having the same issue

mufarrah avatar Jun 26 '22 21:06 mufarrah

same problem! help!

mrleesin avatar Jul 17 '22 15:07 mrleesin

same problem help!!!

emmadedayo avatar Jul 22 '22 14:07 emmadedayo

+1

krasznaidavid avatar Jul 25 '22 14:07 krasznaidavid

I found open issue in Firebase SDK.

There is one workaround and that's passing the registration into getToken, however I'm not sure if it would be possible to implement it in this library.

EDIT: I made a workaround, if anyone wants. Put this in index.html before Flutter init:

const baseRegister = navigator.serviceWorker.register;
navigator.serviceWorker.register = function (url, options) {
  if (url.startsWith('/') && url.indexOf('/', 1) === -1) {
    url = url.substring(1);
  }

  if (options && options.scope && options.scope.startsWith('/') && options.scope.indexOf('/', 1) === -1) {
    options.scope = options.scope.substring(1);
  }

  return baseRegister.call(navigator.serviceWorker, url, options);
};

it could probably be simpler, but I'm not a JS dev.

leoshusar avatar Sep 11 '22 16:09 leoshusar

Please upvote original issue description with thumbs up emoji instead of commenting to ask for updates. Number of upvotes helps the team to prioritize issues.

darshankawar avatar Sep 12 '22 05:09 darshankawar

Any update on the issue? The only way I could make it work was moving firebase-messaging-sw.js to the root folder.

Hey. What do you mean by root folder? I have this firebase-messaging-sw.js file in the web folder which is generated by flutter. But I still have the same problem. I know it was a long time ago, but maybe you remember :)

RomanKuzo avatar Mar 06 '23 13:03 RomanKuzo

@darshankawar any updates? It's really sad that this problem has been around for so long. If there is no new version with a fix, maybe you have some custom solution?

RomanKuzo avatar Mar 17 '23 22:03 RomanKuzo

having the same issue

Astramo avatar Nov 12 '23 07:11 Astramo

This issue is upstream from FlutterFire, you can follow the open issue on the Firebase web JS SDK here: https://github.com/firebase/firebase-js-sdk/issues/2582

There are a couple of workarounds suggested on this thread, but I'd suggest you thumb up the issue in that repo if you wish to see this issue expedited.

russellwheatley avatar Dec 20 '23 16:12 russellwheatley