npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

fcm-messages

v0.0.4

Published

Small library to use Firebase cloud messaging without firebase javascript

Downloads

8

Readme

FCM Cloud messages

Introduction

This library is created for using web push for firebase cloud messages, without firebase.

Found difficulty to use fcm messages in firebase, from one point of view there is firebase with full API, but disadvantage, you have to load full firebase API libraries, for very small use case. Developers, usually like to control, what they are doing. Ant not load unnecessary dependencies. I kept this library as small as possible. Only for Server side push I use web-push library, on client use native API. Uncompressed client has 5kb. I not added compressed version, because developers usually use Webpack or rollup to optimise your code.

Installation

Run npm install fcm-messages

Server Setup

For Server need express installed. Then need for Server.js following setup. Full Example in /examples/service

    
    import express from 'express';
    import bodyParser from 'body-parser';
    import {subscription, storage, webPush} from 'fcm-messages';
 
    const vapidKeys = {
        publicKey:  '...',
        privateKey: '...'
    };
    const messenger = webPush('http://example.com', vapidKeys);
            
    
    const expressApp = express();
    expressApp.use(bodyParser.json());
    
    //Set your static Directory
    expressApp.use(express.static('./'));
    
    // I provide in memory storage, but there can be any with Promise base set, get, delete interface.
    const subscriptions = storage();
    
    // Adding subscription API in to REST
    expressApp.use('/api/v1', subscription(subscriptions).run());
    
    //Expose public key access via REST.
    expressApp.get('/api/v1/key', async (req, resp) => {
        const {key} = messenger;
        resp.send({
            status: 'Success',
            key
        })
    });
    //Message content
    const message = (message) => {
        return JSON.stringify({
            icon:  'images/icon.png',
            badge: 'images/badge.png',
            body: message
        })
    };
    
    // Optional in this example, can send push notifications, via REST interface, usually want to set some cron job or similar.
    expressApp.get('/push/:uid/:content', async (req, resp) => {
        const {uid, content} = req.params;
        const {data} = await subscriptions.get(uid);
        return data ? messenger.sendNotification(data, message(content))
            .then((data) => resp.send(data))
            .catch(error => resp.send(error)) : resp.send({
            status:  'Error',
            message: 'No data found'
        });
    });
    
    expressApp.listen(5050, () => console.log('Example app listening on port 5050!'));

Client setup

For client need setup Service worker ready for Push messaging, and on client side make it ready for push notifications.

In Service Worker

    // Install and activate, probably you will do your own staff as well.
    self.addEventListener('install', (event) => {
        self.skipWaiting();
    });
    self.addEventListener('activate', (event) => {
        self.skipWaiting();
    });
    
    self.addEventListener('push', (event) => {
        const title = 'FCM PUSH';
    
        event.waitUntil(self.registration
            .getNotifications()
            .then(notifications => {
                //Close existing notifications, also, you can collet dta from existing, and update.
                notifications.map(existingNotification => existingNotification.close());
                
                // Send Notification.
                return self.registration.showNotification(title, event.data.json());
            }));
    });

In Client javascript, need to make subscription.

        //need configuration in rollup or webpack
        import {subscriptionManager} from "fcm-messages/client/index";

        //...
        const initialiseUI = ({checkSubscription, updateSubscription})=> {
            //First Check if there is subscription already.
            checkSubscription()
                .then(subscription => {
                    console.log(subscription);
                    updateSubscriptionText(subscription);
                })
                .catch(() => {
                    console.log('User is NOT subscribed.')
                    updateSubscriptionText(false);
                });
            // by toggling button, you can subscribe unsubscribe event.
            pushButton.addEventListener('click', () =>
                updateSubscription()
                .then(subscription => updateSubscriptionText(subscription)));
        
        }
        
        if ('serviceWorker' in navigator && 'PushManager' in window) {
            console.log('Service Worker and Push is supported');
            //Registering Service Worker and initialise subscriptionManager.
            navigator.serviceWorker.register('sw.js')
                .then(function(swReg) {
                    console.log('Service Worker is registered', swReg);
                    initialiseUI(subscriptionManager(swReg, {uid}));
                })
                .catch(function(error) {
                    console.error('Service Worker Error', error);
                });
        } else {
            console.warn('Push messaging is not supported');
            pushButton.textContent = 'Push Not Supported';
        }

API

Client API

/**
 * Creates set of methods to manage push notifications.
 * @param {pushManager} pushManager - Service Worker PushManager.
 * @param {rootURI,uid} options - Params for rootURI and uid (uid is mandatory param)
 * @return {*} list of methods.
 */
const subscriptionManager = ({pushManager}, options = {}) => ({
        /**
        * @method Checking, if user have subscription for notifications
        * @return {Promise}

         * */
        checkSubscription() {
            ...
        },
        /**
         * @method Subscribe user for notifications
         * @return {Promise}
         * */
        subscribeUser() {
            ...
        },
        /**
         * @method remove user subscription for notifications
         * @return {Promise}
         * */
        unsubscribeUser() {
            ...
        },
        /**
         * @method toggle user subscription for notifications
         * @return {Promise}
         * */
        updateSubscription() {
            ...
        },
        /**
         * @method Same like checkSubscripton, but always returning successful Promise
         * @return {Promise}
         * */
        testSubscription() {
            ...
        }
    });

Server API

    /**
     * Creates subscriptionREST API using Express.
     * @param {Storage} Storage - any Promise key value storage, with get, set, delete interface.
     *                              In this library included in memory storage.
     * @return {Subscription} class.
     */
    class Subscription {
    
        /**
         * @method Set subscription in storage
         * @return {Promise}
         * */
        set(uid, subscription) {
            ...
        }
    
        /**
         * @method Test if subscription exists in storage
         * @return {Promise}
         * */
        get(uid) {
            ...
        }
        /**
         * @method remove subscription exists from storage
         * @return {Promise}
         * */
        delete(uid) {
            ...
        }
        /**
         * @method Start REST service
         * @return {Express Router}
         * */
        run() {
            ...
        }
    
    
    };

Storage API | Interface


    /**
     * Creates in Memory Storage, with interface.
     * @return {Storage} Class.
     */
    class Storage {
        /**
         * @method Set data in storage
         * @return {Promise}
         *
         * Promise.then should look
         *          {
         *              status:"Error"|"Success",
         *              message:{String},
         *              data:{Object}
         *          }
         * */
        set(key, value) {
            ...
        }
        /**
         * @method Get data from storage
         * @return {Promise}
         *
         * Promise.then should look
         *          {
         *              status:"Error"|"Success",
         *              message:{String},
         *              data:{Object}
         *          }
         * */
        async get(key) {
            ...
        }
        /**
         * @optional
         * @method Remove data from storage
         * @return {Promise}
         *
         * Promise.then return Boolean
         * */
        async has(key) {
            ...
        }
        /**
         * @method Remove data from storage
         * @return {Promise}
         *
         * Promise.then should look
         *          {
         *              status:"Error"|"Success",
         *              message:{String},
         *          }
         * */
        delete(key) {
            ...
        }
    
    };

Push Notifications


/**
 * Creates Web Push Class.
 * @param {String} host  - http:// host or mailto:.
 * @optional {obj} keys  private and Public keys, if not set, 'web-push' library will generate
 * @return {WebPush} class.
 */
class WebPush {
    /**
     * Set new Keys for class.
     * @param {String} host  - http:// host or mailto:.
     * @optional {Object} keys  publicKey and privateKey, if not set, 'web-push' library will generate
     */
    generateKeys(host, {publicKey, privateKey})) {
        ...
    }
    /**
     * Set new Keys for class.
     * @return {String} public Notification key.
     */
    get key() {
        ...
    }
    /**
     * Sending notification to fcm server
     * @param subscription
     *      {
     *          "endpoint":"https://fcm.googleapis.com/fcm/send/...",
     *          "expirationTime":...,
     *          "keys":{
     *              "p256dh":"...",
     *              "auth":"..."
     *              }
     *        }
     *
     * Subscription data you getting from Service Worker `pushManager.subscribe`
     * @param {String} message - String or Buffer, to send notification.
     * @return {Promise} Notification status.
     */
    sendNotification(subscription, message) {
        ...
    }
}