activitree / meteor-push

Meteor Push Notifications for Cordova and Web/PWA with Firebase (FCM).
MIT License
27 stars 19 forks source link

Meteor Push Notifications with Firebase-Admin for IOS, Android and Web/PWA (Includes breaking changes when coming from V1).

Project Status: Active – The project has reached a stable, usable state and is being actively developed.

This is running in production with https://www.activitree.com

Activitree

The Firebase API in use: https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages. Most of the API is implemented/adapted. If there is anything extra you need, open an issue and ask a friend to send a commit.

In order to run IOS via FCM, you need to configure the Firebase Project to include Apple APN security certificate. All details here: https://firebase.google.com/docs/cloud-messaging/ios/certs. If you are coming from V1, you no longer need to store the .p8 certificate on your Meteor server, don't forget to delete it.

Firebase Javascript SDK Change log: https://firebase.google.com/support/releases

Under the hood:

Simplified development path: https://github.com/activitree/meteor-push/tree/master

NOTE: whenever you update this Meteor Package, please check if your libraries in the web worker for web Push are up to date.(e.g. firebase-messaging-sw.js)

Main logic:

Server:

Use the Push configurator in the Meteor Startup to have everything set, as well as setting defaults for various notification object keys. (E.g TTL, icon, color, launch screen for IOS, etc).

v3.0.0

Uses 3 env vars:

Now Push can be sent from an existing project in multiple ways for different loads:

Client:

Use the Push configurator to set defaults for Cordova and Web Push.

CordovaPush.push.on('notification', data => {
      console.log('this is my message: ', data)
    })

The repo contains an Example folder with files at the expected location. This is not runnable Meteor project, and it is just intended to offer some convenience in understanding where things go.


For a successful processing of Android, please have all defaults set (althoug you might not have a sound file or icon etc) or send the keys within your notification method. Defaults are set in startup/server/push.js. When Android keys are missing and debuggin is set to true you may receive this error: 'android.data must only contain string values'.

Prerequisites:

meteor add activitree:push

All settings suggested are what worked in testing but you are free to change everything indeed. The Android and IOS ware succesfuly built with Meteor. I mention this because before 1.8.1 I could only build Android with Android Studio.

WebPush and PWA

First read this article to understand the concept and workflow: https://webengage.com/blog/web-push-notification-guide/ or https://www.airship.com/resources/explainer/web-push-notifications-explained/

Copy the worker file in the Example /public to your public folder. This needs to be available at https://www.your_address.com/firebase-messaging-sw.js. This worker is responsible for handling backgroud messages.

You can import two hooks: import { webPushSubscribe, webPushUnsubscribe } from 'meteor/activitree:push' Find the example in example/handle_WebPush_In_UX/Notification.js (React version). The method used for sending the message is at imports/api/collection/notifications/methods.js

IOS

After IOS Build, go to /app/.meteor/local/cordova-build/platforms/ios and (if you use Terminal) run 'pod install'. After this, in XCode, update the IOS version for each and every pod installed.

In Meteor 1.8.1 with xCode 11, better use a Lecacy Build System (File/Workspace Settings...) to avoid varios issue related to old Cordova tech not keeping up with the fast pace of Swift development.

Cordova-push-plugin will automatically set IOS through FCM if it sees a GoogleService-Info.plist in the IOS project root. Ideally you would have this in your mobile-config (src would be your prefered location) and make sure that you see this configuration withing the IOS config.xml file.

App.appendToConfig(`
<platform name="ios">
  <resource-file target="GoogleService-Info.plist" src="https://github.com/activitree/meteor-push/raw/master/./../../cordova-build-override/GoogleService-Info.plist"/>
</platform>
`)

Android

On the first build it will eventually fail due to wrong/inadequate Gradle configuration. However the first build is necessary in order to build the files we are going to work with.

This repo contains sample files of configurations that worked in testing. You will find the files at a similar locations to what you would expect to see in you Meteor. At the time of this writing, Firebase Messaging Android plugin is at 20.0.0. That didn't work with Gradle 4.10 and cordova-push-plugin. To avoid any issues, and if you're not targetting AndroidX or other complexities, just use the versions suggested in this repo, withing the gradle related files.

Under /app/.meteor/local/cordova-build/platforms/android/app you need to have a google-service.json file.

In ..cordova-build/platforms/android/project.properties make sure you have the latest versions or fairly new. Initially this will have generic versions or "+" versions (see file in the repo)

In ..platforms/android/build.gradle and everywhere else, you can replace

maven {
            url "https://maven.google.com"
        }

with google(). This replacement covers Gradle 4.1+

In this repo you may find copies of the most import files with relevance for Android so you can have as a comparison.

Gradle used: 4.10.2 Follow this discussion in case you are unable to move up from 4.1 or older https://stackoverflow.com/questions/49321000/minimum-supported-gradle-version-is-4-1-current-version-is-3-3

platforms/android/app/build.gradle
platforms/android/cordova/lib/builders/GradleBuilder.js
platforms/android/cordova/lib/builders/StudioBuilder.js
platforms/android/build.gradle
In /android/app/build.gradle find this part of the code.

task wrapper(type: Wrapper) {
    gradleVersion = '4.10.2'
}

In GradleBuilder.js find this part of the code:
var distributionUrl = process.env['CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL'] || 'https\\://services.gradle.org/distributions/gradle-4.10.2-all.zip';

In StudioBuilder.js find this part of the code:
 var distributionUrl = process.env['CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL'] || 'https\\://services.gradle.org/distributions/gradle-4.10.2-all.zip';
In last file /android/build.gradle we change the following line to actual version. 
classpath 'com.android.tools.build:gradle:3.3.2'

You can also set your prefered Gradle version by running the next command before runnign Meteor: export CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip

About:

The code is linted with Standard.

If you are looking for premium support for this implementation or particular features, please drop a message.

This was tested with:

Google release notes for libraries used by activitree:push:

https://firebase.google.com/support/release-notes/admin/node https://firebase.google.com/support/release-notes/js