flutterfire icon indicating copy to clipboard operation
flutterfire copied to clipboard

πŸ› [firebase_messaging] Web doesn't show notifications when the tab is covered by other windows

Open devxpy opened this issue 2 years ago β€’ 10 comments

fireabase_messaging_web only shows notifications if the tab is closed or the user switches to a different tab.

This means the user doesn't get notifications when

  • User switches to another OS window but leaves the tab open
  • User switches to another chrome window but leaves the tab open
  • The website is Added to the home screen and is running in the background

What's also weird is that in this case, the FirebaseMessaging.onMessage event is fired.

This means there's no way to differentiate it from when the tab is active and in user's focus -- can't correct this using the onMessage / onBackgroundMessage handlers then.

Since our users don't seem to close tabs & use the A2HS feature too, it seems like there's no way to implement reliable notifications on the web via firebase.

If we look at how WhatsApp web works, it won't show you notifications if you're using the website. But as soon as you switch away to another app, it shows you notifications. Can the same behaviour be replicated using firebase_messaing?

devxpy avatar Jun 19 '22 18:06 devxpy

@devxpy We have not found a way to communicate with the Flutter app from the background, which is why you might be seeing the behavior. We have documented the workaround here for web applications, and we will update the documentation once we have a solution.

Based on above explaination, the link and current limitation, I am going ahead and closing this for now. If you disagree, write in comments and I'll reopen it.

darshankawar avatar Jun 20 '22 11:06 darshankawar

I am aware of this limitation. However, as described in the original post, the onBackgroundMessage (even the JS worker one) does NOT get called when the tab is still active but covered by other OS windows. I don’t think the above article covers this case, hence urge you to repoen this ticket. Thanks!

devxpy avatar Jun 20 '22 14:06 devxpy

Thanks for the feedback. Reopening.

darshankawar avatar Jun 21 '22 06:06 darshankawar

@devxpy Can you provide flutter doctor -v, plugin version along with complete minimal reproducible code sample and steps to replicate that we can use to debug this behavior further ?

darshankawar avatar Jun 21 '22 07:06 darshankawar

[βœ“] Flutter (Channel stable, 2.10.5, on macOS 12.4 21F79 darwin-arm, locale en-IN)
    β€’ Flutter version 2.10.5 at /Users/dev/Tools/flutter
    β€’ Upstream repository https://github.com/flutter/flutter.git
    β€’ Framework revision 5464c5bac7 (9 weeks ago), 2022-04-18 09:55:37 -0700
    β€’ Engine revision 57d3bac3dd
    β€’ Dart version 2.16.2
    β€’ DevTools version 2.9.2

[βœ“] Android toolchain - develop for Android devices (Android SDK version 31.0.0-rc3)
    β€’ Android SDK at /Users/dev/Library/Android/sdk
    β€’ Platform android-31, build-tools 31.0.0-rc3
    β€’ Java binary at: /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/bin/java
    β€’ Java version OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_275-b01)
    β€’ All Android licenses accepted.

[βœ“] Xcode - develop for iOS and macOS (Xcode 13.2.1)
    β€’ Xcode at /Applications/Xcode.app/Contents/Developer
    β€’ CocoaPods version 1.11.3

[βœ“] Chrome - develop for the web
    β€’ Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[!] Android Studio (not installed)
    β€’ Android Studio not found; download from https://developer.android.com/studio/index.html
      (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).

[☠] IntelliJ IDEA Ultimate Edition (the doctor check crashed)
    βœ— Due to an error, the doctor check did not complete. If the error message below is not helpful, please let us know about this issue at https://github.com/flutter/flutter/issues.
    βœ— FormatException: Unexpected extension byte (at offset 5)
    β€’ #0      _Utf8Decoder.convertSingle (dart:convert-patch/convert_patch.dart:1789:7)
      #1      Utf8Decoder.convert (dart:convert/utf.dart:351:42)
      #2      InputStream.readString (package:archive/src/util/input_stream.dart:207:30)
      #3      new ZipDirectory.read (package:archive/src/zip/zip_directory.dart:40:30)
      #4      ZipDecoder.decodeBuffer (package:archive/src/zip_decoder.dart:19:30)
      #5      ZipDecoder.decodeBytes (package:archive/src/zip_decoder.dart:14:12)
      #6      IntelliJPlugins._findPluginXml (package:flutter_tools/src/intellij/intellij.dart:130:44)
      #7      IntelliJPlugins._readPackageVersion (package:flutter_tools/src/intellij/intellij.dart:141:40)
      #8      IntelliJPlugins.validatePackage (package:flutter_tools/src/intellij/intellij.dart:63:35)
      #9      IntelliJValidator.validate (package:flutter_tools/src/intellij/intellij_validator.dart:103:15)
      #10     asyncGuard.<anonymous closure> (package:flutter_tools/src/base/async_guard.dart:111:32)
      #11     asyncGuard.<anonymous closure> (package:flutter_tools/src/base/async_guard.dart:109:18)
      #12     _rootRun (dart:async/zone.dart:1426:13)
      #13     _CustomZone.run (dart:async/zone.dart:1328:19)
      #14     _runZoned (dart:async/zone.dart:1861:10)
      #15     runZonedGuarded (dart:async/zone.dart:1849:12)
      #16     runZoned (dart:async/zone.dart:1780:12)
      #17     asyncGuard (package:flutter_tools/src/base/async_guard.dart:109:3)
      #18     Doctor.startValidatorTasks (package:flutter_tools/src/doctor.dart:205:9)
      #19     Doctor.diagnose (package:flutter_tools/src/doctor.dart:309:47)
      #20     DoctorCommand.runCommand (package:flutter_tools/src/commands/doctor.dart:50:48)
      #21     FlutterCommand.verifyThenRunCommand (package:flutter_tools/src/runner/flutter_command.dart:1320:12)
      <asynchronous suspension>
      #22     FlutterCommand.run.<anonymous closure> (package:flutter_tools/src/runner/flutter_command.dart:1161:27)
      <asynchronous suspension>
      #23     AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
      <asynchronous suspension>
      #24     CommandRunner.runCommand (package:args/command_runner.dart:209:13)
      <asynchronous suspension>
      #25     FlutterCommandRunner.runCommand.<anonymous closure> (package:flutter_tools/src/runner/flutter_command_runner.dart:281:9)
      <asynchronous suspension>
      #26     AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
      <asynchronous suspension>
      #27     FlutterCommandRunner.runCommand (package:flutter_tools/src/runner/flutter_command_runner.dart:229:5)
      <asynchronous suspension>
      #28     run.<anonymous closure>.<anonymous closure> (package:flutter_tools/runner.dart:62:9)
      <asynchronous suspension>
      #29     AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
      <asynchronous suspension>
      #30     main (package:flutter_tools/executable.dart:94:3)
      <asynchronous suspension>


[βœ“] IntelliJ IDEA Ultimate Edition (version 2021.3.2)
    β€’ IntelliJ at /Users/dev/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/213.6777.52/IntelliJ IDEA.app
    β€’ 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

[βœ“] VS Code (version 1.56.2)
    β€’ VS Code at /Applications/Visual Studio Code.app/Contents
    β€’ Flutter extension version 3.22.0

[βœ“] Connected device (2 available)
    β€’ macOS (desktop) β€’ macos  β€’ darwin-arm64   β€’ macOS 12.4 21F79 darwin-arm
    β€’ Chrome (web)    β€’ chrome β€’ web-javascript β€’ Google Chrome 102.0.5005.115
    ! Error: iPad is not connected. Xcode will continue when iPad is connected. (code -13)

[βœ“] HTTP Host Availability
    β€’ All required HTTP hosts are available

! Doctor found issues in 2 categories.

devxpy avatar Jun 21 '22 10:06 devxpy

firebase-messaging-sw.js

// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here. Other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js');

// Initialize the Firebase app in the service worker by passing in
// your app's Firebase config object.
// https://firebase.google.com/docs/web/setup#config-object
firebase.initializeApp({
  apiKey: 'api-key',
  authDomain: 'project-id.firebaseapp.com',
  databaseURL: 'https://project-id.firebaseio.com',
  projectId: 'project-id',
  storageBucket: 'project-id.appspot.com',
  messagingSenderId: 'sender-id',
  appId: 'app-id',
  measurementId: 'G-measurement-id',
});

// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();

messaging.onBackgroundMessage((payload) => {
    console.log('[firebase-messaging-sw.js] Received background message ', payload);
});

Repro steps -

  1. Open webpage
  2. Open console
  3. Switch (cmd+tab) to another app
  4. Send a notification from firebase console / Server SDK

Observed behaviour -

  • Notice you don't see any notification or any log in the console

Expected behavior -

  • See a log in the console from the onBackgroundMessage handler
  • See a notification from the browser

Notes -

  • Before step (3), if you close or change the tab, you get the expected behavior

devxpy avatar Jun 21 '22 10:06 devxpy

Thanks for the update. Using above code and steps to replicate, I do see the same behavior as reported, although, as mentioned the onBackgroundMessage (even the JS worker one) does NOT get called when the tab is still active but covered by other OS windows., this could be a limitation from browser / chrome itself which is why the current behavior.

Also, https://github.com/firebase/flutterfire/issues/8931#issuecomment-1160353683 for reference.

/cc @russellwheatley

darshankawar avatar Jun 21 '22 13:06 darshankawar

That limitation does not seem to be there on the native web push API.


While playing around with this I discovered that even if you manually show a notification using the onMessage handler, there's no way to reliably implement onclick behaviour (e.g. page reloaded after showing notification), because onMessage gets triggered only from the top-level JS context, not the service worker context.

devxpy avatar Jun 21 '22 19:06 devxpy

Couldn't find a solution to this problem?

bahiraei avatar Dec 10 '23 12:12 bahiraei

Can use the BroadcastChannel API to communicate between different documents (in different windows, tabs, frames or iframes) of the same origin. I implement it on TwakeMail project and it was successful. See morehere

dab246 avatar Mar 22 '24 10:03 dab246