Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] Headless task to set image on notification when in background is not being executed #3285

Closed
5 of 10 tasks
taschik opened this issue Mar 9, 2020 · 5 comments
Closed
5 of 10 tasks

Comments

@taschik
Copy link

taschik commented Mar 9, 2020

Issue

I am trying to display images in push notifications on Android when the app is in background. When running in foreground, I see the image in the notification but as soon as the app is in background or even not running, the headless task is not being executed. I can see the notification with text and title but since the headless task is not being executed, the image is not being downloaded and displayed.

I followed the documentation of rnfirebase-(Optional)(Android-only)-Listen-for-FCM-messages-in-the-background) and https://medium.com/@sumedh.tare/react-native-firebase-custom-notification-with-image-d9c2264c7fab

My goal is to see the image when the app is not in foreground too.

We added the following code:
index.android.js

AppRegistry.registerHeadlessTask('RNFirebaseBackgroundMessage', () => bgNotifications)

after registering the Main component.

notifications/bgNotifications.js

import firebase from 'react-native-firebase'
import { get } from 'lodash'

import { NOTIFICATION_CHANNEL } from './firebase'

export default async message => {
  console.log('backgroundAndroidMessage ', message)
  const icon = get(message, 'data.icon', '')
  const notification = new firebase.notifications.Notification({
    body: notification.body + ' love <3',
    title: notification.title,
    sound: 'default',
    show_in_foreground: true,
    data: notification.data,
  })
  notification.android
    .setChannelId(NOTIFICATION_CHANNEL)
    .setNotificationId(message.messageId)
    .setPriority(firebase.notifications.Android.Priority.High)
    .setAutoCancel(true)
    .setVibrate([200, 200, 200, 200])

  if (icon) {
    notification.android.setLargeIcon(icon).android.setBigPicture(icon)
  }
  firebase.notifications().displayNotification(notification)

  return Promise.resolve()
}


MainApplication.java
Added this in the onCreate() function

  SoLoader.init(this, /* native exopackage */ false); // <-- Check this line exists within the block

Unfortunately the headless task is never executed and I never get into the JS part to debug further. That's why I think this may a bug. Any hints are very appreciated on how to fix this.


Project Files

Javascript

Click To Expand

package.json:

{
  "name": "xxx",
  "version": "0.0.1",
  "private": true,
  "engines": {
    "node": ">=10.16.0",
    "npm": ">=6.9.0"
  },
  "scripts": {
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint .",
    "reset-cache": "npm start -- --reset-cache",
    "fix": "prettier-eslint --write \"src/**/*.{js,jsx,json,css}\"",
    "update-i18n": "node ./scripts/update-localizations.js",
    "postinstall": "npx jetify"
  },
  "dependencies": {
    "@react-native-community/art": "^1.1.2",
    "@react-native-community/async-storage": "^1.7.1",
    "@react-native-community/cameraroll": "^1.3.0",
    "@react-native-community/datetimepicker": "^2.2.2",
    "@react-native-community/geolocation": "^2.0.2",
    "@react-native-community/netinfo": "^5.0.0",
    "adyen-cse-js": "git+https://github.com/Adyen/adyen-cse-web.git#v0.1.24",
    "ajv": "^5.5.1",
    "aws-amplify": "^1.2.4",
    "eslint-import-resolver-babel-module": "^4.0.0",
    "fsevents": "^1.2.9",
    "geolib": "^3.2.0",
    "instabug-reactnative": "^9.0.1",
    "jetifier": "^1.6.3",
    "lodash": "^4.17.15",
    "moment": "^2.22.2",
    "moment-timezone": "^0.5.21",
    "node-libs-browser": "2.1.0",
    "normalizr": "^3.2.4",
    "prop-types": "^15.6.1",
    "qs": "^6.7.0",
    "querystring": "^0.2.0",
    "react": "^16.9.0",
    "react-devtools": "^3.4.3",
    "react-devtools-core": "^3.4.3",
    "react-native": "^0.61.5",
    "react-native-adyen-cse": "^1.0.7",
    "react-native-amplitude-analytics": "^0.2.7",
    "react-native-animatable": "^1.3.3",
    "react-native-background-fetch": "^2.7.1",
    "react-native-background-geolocation": "^3.4.2",
    "react-native-branch": "^4.3.0",
    "react-native-calendar-events": "^1.7.3",
    "react-native-check-app-install": "0.0.5",
    "react-native-dark-mode": "^0.2.1",
    "react-native-datepicker": "^1.6.0",
    "react-native-device-info": "^5.4.0",
    "react-native-elements": "^1.2.7",
    "react-native-extended-stylesheet": "^0.12.0",
    "react-native-fabric": "git+https://github.com/xxx/react-native-fabric.git#fix/android-warning",
    "react-native-fast-image": "^7.0.2",
    "react-native-fbsdk": "~1.0.4",
    "react-native-firebase": "^5.6.0",
    "react-native-fs": "^2.16.2",
    "react-native-geolocation-service": "^3.1.0",
    "react-native-gesture-handler": "^1.5.2",
    "react-native-gifted-chat": "git+https://github.com/xxx/react-native-gifted-chat.git#fix/babel-config",
    "react-native-hyperlink": "0.0.18",
    "react-native-i18n": "git+https://github.com/xxx/react-native-i18n.git#fix/androidx",
    "react-native-image-crop-picker": "^0.26.1",
    "react-native-iphone-x-helper": "^1.2.1",
    "react-native-keyboard-aware-scroll-view": "^0.9.1",
    "react-native-keychain": "^4.0.4",
    "react-native-linear-gradient": "^2.5.6",
    "react-native-loading-spinner-overlay": "^1.0.1",
    "react-native-localize": "^1.3.1",
    "react-native-maps": "^0.26.1",
    "react-native-masked-text": "^1.13.0",
    "react-native-offline": "^5.2.0",
    "react-native-pages": "^0.9.0",
    "react-native-permissions": "^2.0.9",
    "react-native-phone-call": "^1.0.9",
    "react-native-progress": "^4.0.3",
    "react-native-rate": "^1.1.10",
    "react-native-read-more-text": "^1.1.0",
    "react-native-reanimated": "^1.4.0",
    "react-native-share": "^2.0.0",
    "react-native-simple-store": "git+https://github.com/xxx/react-native-simple-store.git#master",
    "react-native-smart-gallery": "^1.1.5",
    "react-native-snap-carousel": "^3.8.4",
    "react-native-status-bar-height": "^2.4.0",
    "react-native-swipe-list-view": "^2.1.3",
    "react-native-swipeout": "^2.3.6",
    "react-native-uuid": "^1.4.9",
    "react-native-v8": "^0.61.5-patch.0",
    "react-native-vector-icons": "^6.6.0",
    "react-native-version-check": "^3.3.1",
    "react-native-version-number": "^0.3.6",
    "react-native-webview": "^8.0.0",
    "react-navigation": "^4.0.10",
    "react-navigation-stack": "^1.10.3",
    "react-navigation-tabs": "^2.6.2",
    "react-redux": "7.0.0",
    "redux": "^4.0.4",
    "redux-actions": "^2.3.0",
    "redux-form": "^8.2.5",
    "redux-thunk": "^2.2.0",
    "reselect": "^4.0.0",
    "rmc-picker": "^5.0.10",
    "rn-fetch-blob": "^0.12.0",
    "short-uuid": "^3.1.1",
    "stream": "0.0.2",
    "vm": "^0.1.0"
  },
  "devDependencies": {
    "@babel/core": "^7.6.2",
    "@babel/runtime": "^7.6.2",
    "@react-native-community/eslint-config": "^0.0.5",
    "babel-eslint": "^8.2.2",
    "babel-jest": "^24.9.0",
    "babel-plugin-module-resolver": "^3.1.0",
    "babel-plugin-rewrite-require": "^1.14.5",
    "babel-plugin-transform-inline-environment-variables": "^0.3.0",
    "eslint": "^6.5.1",
    "eslint-config-airbnb": "^17.1.1",
    "eslint-config-prettier": "^6.0.0",
    "eslint-plugin-import": "^2.18.2",
    "eslint-plugin-jest": "^22.21.0",
    "eslint-plugin-jsx-a11y": "^6.0.3",
    "eslint-plugin-react": "^7.14.3",
    "eslint-plugin-react-native": "^3.7.0",
    "firebase-tools": "^7.6.1",
    "jest": "^24.9.0",
    "localize-spreadsheet-bot": "^0.8.5",
    "metro-react-native-babel-preset": "^0.56.0",
    "prettier-eslint": "^8.8.2",
    "prettier-eslint-cli": "^4.7.1",
    "react-test-renderer": "16.9.0",
    "redux-devtools-extension": "^2.13.2",
    "remote-redux-devtools": "^0.5.12",
    "schedule": "^0.4.0"
  },
  "jest": {
    "preset": "react-native",
    "transformIgnorePatterns": [
      "/node_modules/(?!native-base)/"
    ]
  },
  "rnpm": {
    "assets": [
      "./assets/fonts"
    ]
  }
}

iOS

Click To Expand

ios/Podfile:

  • I'm not using Pods
  • I'm using Pods and my Podfile looks like:
# N/A

AppDelegate.m:

// N/A


Android

Click To Expand

Have you converted to AndroidX?

  • my application is an AndroidX application?
  • I am using android/gradle.settings jetifier=true for Android compatibility?
  • I am using the NPM package jetifier for react-native compatibility?

android/build.gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {

    ext {
		googlePlayServicesLocationVersion = "17.0.0"
        buildToolsVersion = "28.0.3"
        minSdkVersion = 18
        compileSdkVersion = 28
        targetSdkVersion = 28
        supportLibVersion = "1.0.0"  // <-- IMPORTANT:  For new AndroidX compatibility.
    }

    repositories {
        google()
        jcenter()
        maven { url 'https://maven.google.com' }
        maven { url 'https://maven.fabric.io/public' }
        mavenCentral()
    }


    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.2'
        classpath 'com.google.gms:google-services:4.3.2'
        classpath 'io.fabric.tools:gradle:1.31.1'
    }
}

subprojects { subproject ->
    afterEvaluate{
        if((subproject.plugins.hasPlugin('android') || subproject.plugins.hasPlugin('android-library'))) {
            android {
                compileSdkVersion 28
                buildToolsVersion "28.0.3"
            }
        }
    }
    project.configurations.all {
        resolutionStrategy.eachDependency { details ->
            if (details.requested.group == 'com.android.support'
                    && !details.requested.name.contains('multidex') ) {
                details.useVersion "27.0.2"
            }
        }
    }


}

allprojects {
    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
        }
    }
    repositories {
        // google needs to be first spot & above jcenter because of firebase - https://rnfirebase.io/docs/v4.3.x/installation/android
        google()
        jcenter()
        maven { url "https://www.jitpack.io" }
        maven { url 'https://maven.google.com' }
        maven { url 'https://maven.fabric.io/public' }
        maven {
      	    url "https://sdks.instabug.com/nexus/repository/instabug-cp"
       	}
        mavenCentral()


        maven {
			      url "$rootDir/../node_modules/react-native-background-fetch/android/libs"
	      }        

        mavenLocal()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            // url("$rootDir/../node_modules/react-native/android")
            // Replace AAR from original RN with AAR from react-native-v8
            url("$rootDir/../node_modules/react-native-v8/dist")
        }
        maven {
            // prebuilt libv8.so
            url("$rootDir/../node_modules/v8-android/dist")
        }
        maven {
            // Android JSC is installed from npm
            url("$rootDir/../node_modules/jsc-android/dist")
        }

    }
}

android/app/build.gradle:

// N/A

android/settings.gradle:

// N/A

MainApplication.java:

// N/A

AndroidManifest.xml:

 <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="xxx-channel"/>
      <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@mipmap/ic_launcher_round" />
      <meta-data android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/xxx_color" />
      <service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService" android:exported="false">
          <intent-filter>
              <action android:name="com.google.firebase.MESSAGING_EVENT" />
          </intent-filter>
      </service>

      <service android:name="io.invertase.firebase.messaging.RNFirebaseBackgroundMessagingService" />```

</p>
</details>

Environment

Click To Expand

react-native info output:

System:
    OS: macOS 10.15.3
    CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
    Memory: 57.07 MB / 32.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 10.16.3 - /usr/local/bin/node
    Yarn: 1.17.3 - /usr/local/bin/yarn
    npm: 6.9.0 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
    Android SDK:
      API Levels: 23, 26, 27, 28, 29
      Build Tools: 23.0.1, 25.0.0, 26.0.3, 27.0.3, 28.0.1, 28.0.2, 28.0.3
      System Images: android-24 | Google APIs Intel x86 Atom, android-24 | Google Play Intel x86 Atom, android-27 | Google APIs Intel x86 Atom, android-28 | Google APIs Intel x86 Atom, android-29 | Google APIs Intel x86 Atom
  IDEs:
    Android Studio: 3.6 AI-192.7142.36.36.6241897
    Xcode: 11.3.1/11C504 - /usr/bin/xcodebuild
  npmPackages:
    react: ^16.9.0 => 16.9.0
    react-native: ^0.61.5 => 0.61.5
  npmGlobalPackages:
    eslint-plugin-react-native: 3.5.0
    react-native-cli: 2.0.1
    react-native-git-upgrade: 0.2.7

  • Platform that you're experiencing the issue on:
    • iOS
    • Android
    • iOS but have not tested behavior on Android
    • Android but have not tested behavior on iOS
    • Both
  • react-native-firebase version you're using that has this issue:
    • e.g. 5.4.3
    • 5.6.0
  • Firebase module(s) you're using that has the issue:
    • e.g. Instance ID
  • Are you using TypeScript?
    • Y/N & VERSION
    • N


Think react-native-firebase is great? Please consider supporting all of the project maintainers and contributors by donating via our Open Collective where all contributors can submit expenses. [Learn More]

@mikehardy
Copy link
Collaborator

what's unfiltered logcat look like? You should see the headless task starting. I noticed in my implementation that it had to be registered before AppContainer was created and loaded
All I can say is that it definitely works, why it's not working here could be for any of a pile of reasons, but unfiltered logcat in combo with lots of console.log statements as things (should) happen can hopefully shed light

@luatnd
Copy link

luatnd commented Mar 10, 2020

Another issue led me here. I did sth like this 6 months ago using react-native firebase and I think you're missing sth:

First, if your purpose is displaying large image without customize the UI, android notification has already supported that without any background service.
https://firebase.google.com/docs/cloud-messaging/android/send-image

Second, If you still need to use data message, you might have missed some Manifest entry:
https://rnfirebase.io/docs/v5.x.x/messaging/android

@taschik
Copy link
Author

taschik commented Mar 11, 2020

@luatnd thanks for pointing this out!

I found the working solution eventually in here https://stackoverflow.com/a/58334833/1683304 which pointed me to the extra_notification_kwargs that I needed to add, which adds the image field that Android automatically displays when the app is in the background. Thanks so much for the help.

@mikehardy perhaps it makes sense to add this information to the documentation. Either way, you guys might update the documentation to reflect the registration of the headless task has to come before! the registration of the Main component. Currently it's the other way around.

@taschik taschik closed this as completed Mar 11, 2020
@mikehardy
Copy link
Collaborator

@mikehardy perhaps it makes sense to add this information to the documentation. Either way, you guys might update the documentation to reflect the registration of the headless task has to come before! the registration of the Main component. Currently it's the other way around.

One of the downsides to maintenance is you lose track of the initial steps because you don't do them all the time, so people that have just gone through something are actually much more equipped to make these sorts of changes - for that reason there is an edit button at the top of every document page and making doc PRs on github is an incredibly quick process (they handle all the fork/branch/make-PR stuff in just a couple clicks all on the web)

@taschik
Copy link
Author

taschik commented Mar 11, 2020

@mikehardy perhaps it makes sense to add this information to the documentation. Either way, you guys might update the documentation to reflect the registration of the headless task has to come before! the registration of the Main component. Currently it's the other way around.

One of the downsides to maintenance is you lose track of the initial steps because you don't do them all the time, so people that have just gone through something are actually much more equipped to make these sorts of changes - for that reason there is an edit button at the top of every document page and making doc PRs on github is an incredibly quick process (they handle all the fork/branch/make-PR stuff in just a couple clicks all on the web)

Thanks so much and apologies. I wasn't aware the community is allowed to edit them. Did it right away: invertase/react-native-firebase-docs#251

Thanks Mike!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants