0

I am experimenting with push-notifications sent from a Node.js app. Following some tutorial and examples, I now have a working mini-application to start with.

It is basically composed of four files: index.js, index.html, worker.js and client.js.

To get to understand how it all works (and clean the code at the same time) and become familiar with it all. I started by replacing this:

const privateVapIdKey = 'my-secret-1213131...privVapIdKey',
      publicVapIdKey = 'my-secret-3453754...pubVapIdKey';

by this:

const privateVapIdKey = process.env.privVapIdKey,
      publicVapIdKey = process.env.pubVapIdKey;

in index.js.

And it worked. Then I tried replacing this:

const publicVapIdKey = 'my-secret-3453754...pubVapIdKey';

by this:

const publicVapIdKey = process.env.pubVapIdKey;

in client.js. But this time it did not work.

Why does it work when I do the code change in index.js and not in client.js?

It shows that the 2 files do not share the same kind of access to process.env.

But what is the right way to do here?

For reference I put here the two relevant files:

index.js:

const express = require('express'),
      webPush = require('web-push'),
      bodyParser = require('body-parser'),
      path = require('path');
const app = express();

app.use(express.static(path.join(__dirname, 'client')));
app.use(bodyParser.json());

const privateVapIdKey = process.env.privVapIdKey,
      publicVapIdKey = process.env.pubVapIdKey;

webPush.setVapidDetails(
    'mailto:myemail@example.com',
    publicVapIdKey,privateVapIdKey);

// Subscribe Route.
app.post('/subscribe',(req,res) => {
    const subscription = req.body; // Get Push Subscription Object.
    res.status(201).json({}); // Send 201. Resource created.

    // Do a lot of useful things ......
    .......
    // Create the PayLoad.
    const payload = JSON.stringify({
        title:'A big title!',
        ........
    });
    // Pass Object to sendNotification.
    webPush.sendNotification(subscription,payload).catch(err => console.error(err));
});

const port = 5003;

const PORT = process.env.PORT || port;
app.listen(PORT, () => console.log(`Listening on ${ PORT }`));

client.js:

const publicVapIdKey = 'my-secret-3453754...pubVapIdKey';
//const publicVapIdKey =  process.env.pubVapIdKey; // This is not working!!

// Chec for ServiceWorker.
if ('serviceWorker' in navigator) {
    send().catch(err => console.error(err));
}


// Register ServiceWorker, Register Push, Send Push.
async function send() {
    console.log("Registering ServiceWorker.");
    const register = await navigator.serviceWorker.register('/worker.js', {
        scope: "/"
    });
    console.log('ServiceWorker registered.');

    console.log("Registering Push.");
    //register.pushManager.uns
    const subscription = await register.pushManager.subscribe({
        userVisibleOnly: true,
        applicationServerKey: urlBase64ToUint8Array(publicVapIdKey)
    });
    console.log('Push registered.');

    console.log("Sending Push.");
    await fetch('/subscribe', {
        method: 'POST',
        body: JSON.stringify(subscription),
        headers: {
            'content-type': 'application/json'
        }
    });
    console.log('Push sent.');
}


function urlBase64ToUint8Array(base64String) {
    const padding = '='.repeat((4 - base64String.length % 4) % 4);
    const base64 = (base64String + padding)
      .replace(/\-/g, '+')
      .replace(/_/g, '/');

    const rawData = window.atob(base64);
    const outputArray = new Uint8Array(rawData.length);

    for (let i = 0; i < rawData.length; ++i) {
      outputArray[i] = rawData.charCodeAt(i);
    }

    return outputArray;
}
Michel
  • 10,303
  • 17
  • 82
  • 179
  • May I know, how and where are you setting these keys as environment variables? If you are setting the environment variables from index.js and client.js is a different process, then client.js cannot access them. – Sreehari Jun 03 '18 at 07:51
  • These variables are set as configuration variable on the Heroku Dashboard. (i.e. https://dashboard.heroku.com/apps/myapp/settings) – Michel Jun 03 '18 at 07:55
  • That is not inside index.js. – Michel Jun 03 '18 at 08:22
  • `process.env` is server side global variable, you cannot use it during runtime on client-side – kkkkkkk Jun 03 '18 at 08:40
  • OK. That makes it clear. Then I need to keep the variable hard-coded inside client.js. – Michel Jun 03 '18 at 08:43

0 Answers0