How to get push notifications working with Expo on the App and Play stores

I’ve been working on a react native app called Deep Connections on and off for a few years, and using it to test various technologies.

I looked into getting push notifications working within an Ionic app I had built, but just found myself struggling too much with Android Studio and Xcode configurations.

So I decided to test out the push notifications in Expo, using my Deep Connections app as a test bed. I got it working, and this is how I did it.

The Push Notifications Overview in Expo docs are pretty good.

Firstly, we need to get a user’s Expo Push Token. Modifying the code from the docs, I created a module called registerForPushNotificationsAsync.js to include as the app starts up to get that token. And then I’ve created a minimalist function called sendPushNotification.js to demo how to take a message and an array of Expo Push Tokens to send out the same message to every Expo Push Token.

Once I have the Expo Push Token for a user, I store it in Firebase to use later to send push notifications with. Note that you can only retrieve an Expo Push Token from a physical device. This won’t work with simulators.

Expo has a neat Push Notification Tool, that you can immediately test out push notifications with the retrieved Expo Push Token. This will work fine while you’re developing within the Expo ecosystem.

If you’re going to deploy your app to the App and Play stores some extra setup needs to be done.

To setup Expo to work with Android, follow this guide to configure Firebase Cloud Messaging, and how to upload server credentials to Expo.

And then finally to get Expo working for iOS, follow these steps.

How To Create Sacred Geometry With JavaScript

Sacred geometry requires perfectly formed shapes that are perfectly positioned in relation to each other. This is very difficult to do by hand, so I thought I’d give it a go using code.

I’m going to use React, together with Konva.js to be able to draw on the HTML5 canvas element.

This is the final result..

If you’re interested in looking at the code, click here.

Some things I learned along the way

To create the seed of life, draw a circle, then draw another six circles at degree 0, 60, 120, 180, 240, 300.

To calculate the coordinate of where to draw the new circle, where you can use some trigonometry to calculate the coordinate for the center of the next circle. To use JavaScript’s Math.cos and Math.sin functions though, you need to first convert degrees to radians. The following two functions do both these tasks for you.

You can view the generated seed of life here.

The flower of life certainly looks a lot more complicated, but it is in fact created in the exact same way as the seed of life above. The only difference, is that instead of seven circles in the seed of life, the flower of life has seven seeds of life!

You can view the generated flower of life here.

For the flower of life I also added two circles around the outside of the full design to more closely match the design seen widely.

Privacy and Security Tools

For almost everyone

This section is for almost everyone who isn’t necessarily tech savvy, yet are still concerned about their privacy and security online. The following tips are designed to probably dramatically increase your privacy and security online in a way that’s pretty easy to do, and free.

When browsing the web, get Firefox, and then install the uBlock Origin and DuckDuckGo Privacy Essentials plugins.

For logins on websites, get the LastPass Password Manager plugin for Firefox. This will manage logins for all your websites. You just need to create one really strong password to access your password vault.

For secure group chats, and to share files, try Keybase. This is like a more secure form of Slack. You could totally use it for social type networks.

For secure messaging and calls from your phone, use Signal.

Email isn’t very secure, but if you are going to use it, try ProtonMail.

Using a VPN hides your true location from most, and makes sure your traffic is encrypted even on public networks. I currently use ProtonVPN.

To avoid a lot virus and malware issues, use either a Mac or Linux.

I also highly recommend the book Permanent Record by Edward Snowden. It’s essentially about how governments are involved in mass surveillance of everyone.


If you have any questions or feedback, please comment below.


For the more technically minded

This section is for the tech savvy people out there that want to take their security and privacy levels up another notch.

Setup your own VPN using a cloud provider like DigitalOcean and Algo VPN. Walk through doc here.

For even more private web browsing use the Tor Browser. For a detailed discussion of what browser to choose, read this.

To view your public IP address using the command line:

  • dig +short
  • curl (more information)

To ensure higher privacy of your data, make a backup of your machine’s data to an external HDD instead of some cloud service. A suggested tool is BorgBackup.

For free OS X security tools, check out Objective-See.


For anyone in the know with security and privacy in the digital space, contributions are welcome. Please add your thoughts in the comments below.

Speech Recognition For Speech to Text Using JavaScript

I’ve been playing with Speech Recognition technologies for a long time now. But I never really liked it that people had to download and install an application on their computer to use my application.

And then Google Chrome created an implementation for the Web Speech API. And it works great.

To see a working demo you can play with, click here.

I built an npm module to make it a little easier to integrate speech-to-text into your client-side app. You can download it here. For your speech recognition app, there are some things you probably want the listener to tell you…

  • Chrome uses the Google Cloud platform to send your audio to, which returns an accurate transcription of what was said. So you probably want to get notified when this happens and what was said from there.
  • You probably want to get notified when the speech recognition engine disconnects and stops listening. So you can reconnect if need be.
  • Chrome also converts speech to text in the browser almost instantly. This is useful to get notified of for your UX while the slightly slower Cloud conversion takes place.

So to instantiate a new object to listen to speech in your app, it will probably look like this

const listener = new SpeechToText(onFinalised, onEndEvent, onAnythingSaid);

where the arguments are callback functions corresponding to our points above.

A sample application apart from the demo above, is to search for images using the voice only. You can view a demo of that here.

How to safely store credentials in GitHub

It is actually pretty convenient to have credentials and keys stored in the same repository as your codebase. Of course this is unsafe, as anyone (if you’re using public repos) can use those credentials to access your infrastructure (databases, servers, 3rd party APIs).

So firstly if your code is not for public use, a private repository obviously improves the security of your credentials immediately.

Bottom line, though, is if you store your credentials in a repository like on GitHub, encrypt those config files and keys first before committing them.

GNU Privacy Guard

For encryption we’ll be using GnuPG.

Install GnuPG

First step is to go and download the binary for your OS here.

Generate a keypair for yourself

Once installed, we need to generate a key pair for ourselves. Open a terminal and type

gpg2 --gen-key

Answer the prompts, and (importantly!) choose a strong passphrase.

Encrypt a file

In your terminal, let’s say we want to encrypt a file called “keys.js” (which might have some config credentials that our codebase uses).


gpg2 -e -a -s -r keys.js

What the parameters mean:

  • -e means to encrypt the file
  • -a means to “create ascii armored output”. Basically you can view the file, instead of it being a binary file.
  • -s means to sign the file
  • -r means to choose which recipient should be able to decrypt the file. In our case I’m using my email address that I used to create the key pair above
  • keys.js is the name of the file I want to encrypt

This will generate a file in the same directory called keys.js.asc.

If you view the file e.g. less keys.js.asc you’ll see something like



To decrypt a file

In your terminal, type

gpg2 -d -o keys.js keys.js.asc

What the parameters mean:

  • -d means to decrypt the file
  • -o specifies the name of the output file to save the decrypted data into. If you don’t specify this option, the decrypted contents will appear in your terminal

You’ll be prompted for your passphrase for your private key.

Update your .gitignore file

Now that we have encrypted our credentials file, make sure you ignore the credentials files, but not the encrypted files.

For example, if your credentials (config files and private keys) are in a config directory, you would update the .gitignore file to have something like


Now you can safely commit your encrypted credentials

git add .

git commit -a -m "encrypted credentials"

git push

Backing up your private key

Make sure you backup your private key though. As if you lose it you won’t be able to decrypt those committed credentials.

To export your private key, type

gpg2 --export-secret-key -a -o andrew-golightly.asc 'Andrew Golightly'

Which will export your private key in ascii armored output to andrew-golightly.asc

To store it, there are a number of things you could do.

One way is to zip that file and encrypt it, and store it on a backup (encrypted) USB or external disk.

To zip and encrypt a file on a Mac, type:

zip -e andrew-golightly.asc

You’ll be prompted for a password to encrypt the zip with.

Oh and make sure you remember your passphrase too :)

How to automatically restart forever (for Node.js scripts and servers) on a system reboot

I use forever to start my Node.js scripts, to ensure that if it crashed, it would just auto-restart.

An issue arises though if the server itself reboots. Which for some reason happened on a DigitalOcean droplet I was using. So I needed to figure out a way to restart the forever process on system reboot. I couldn’t find any clear documentation, but this is the solution I finally figured out after piecing together various bits of information online together. The most helpful source of this answer came from an answer on stack overflow.

First, run

crontab -u root -e

then after all the comments add this content:

Some key points here:

  1. you can explicitly set any environment variables you need in here for the script to work
  2. you must include your path to your Node.js executable. This PATH seems to normally load only after the crontab is run.

This certainly helps make your Node.js servers and scripts much more robust.

How to add a subdomain to an existing certificate using certbot

You’re probably reading this because you already have a Let’s Encrypt certificate issued using certbot for a domain, and now want to add-on subdomains.

If you want to create a new certificate, have a look at the end of this article.

In my case I already had a certificate which covered


I have a directory on my server called dev that I want to reference via

So to do that, I issued the following command

certbot -d,, --expand

Key takeaways:

  1. re-include every domain name you want on that certificate again. I forgot www. the first time. No biggie, just re-run with all the domains you want.
  2. don’t forget to add --expand to the end

After reading around on the net a bit, I found this solution on this GitHub thread.

How to automatically and permanently delete unwanted emails

Gmail provides the option to filter unwanted emails to your Bin. Click here for the instructions on how to do that.

The emails though only get automatically permanently deleted after 30 days.

So if you are trying to block someone from emailing you, and you have weak moments and end up checking the trash, you kinda still haven’t removed the temptation properly. Or are not able to put up effective boundaries.

So I built a system that allows users to register and automatically clear their Bin folder every hour.

It’s one of the tools available at my new site

Try it out and let me know how it goes!



How to setup a Node.js server on DigitalOcean

Once your droplet is created and you’ve ssh’d in, it’s time to set some things up..

I start off by installing nvm. You can find the command for the install script here. At the time of writing, I used

curl -o- | bash

I needed to exit my terminal, and then ssh back in.

Then, for me, I want the latest LTS from Node.js installed.

So I run nvm install --lts

Also  I want the lts versions to be my default node with nvm.

So type nvm alias default lts/*

As a personal preference I then clone out my repo to /var/server

Once in there, of course run npm install

Then I like to setup forever, so I can make sure the server runs indefinitely.

npm install -g forever

Then it’s just a matter of starting up your server. So something like

forever start my-server.js

How to setup Nginx for WordPress on DigitalOcean

I decided to switch from Apache to Nginx.

I have a couple of WordPress sites on a DigitalOcean droplet, so I needed to reconfigure them to be used with Nginx. I basically followed this guide which was great for most of it, but I was still not getting the sites loading properly (404 errors, forbidden).

I needed to tweak the server block files to get it working, and this is what I came up with..

In /etc/nginx/sites-available create a separate file for each domain you’re hosting. For one of mine, I called it to correspond with my Go For Self website, and this is the contents of that file…

Then in /etc/nginx/sites-enabled/ create a symlink like so

ln -s ../sites-available/ .

I like to have my sites being only accessed over HTTPS, so there are a couple more steps to get this going. I basically followed this guide, and this is the essence of what needs to be done..

First install certbot

For my Go For Self website setup above, I then type

sudo certbot --nginx -d -d

and I choose option 2 to always redirect to HTTPS.

And that is pretty much it. You’ll need to restart nginx to get it going.. so I go

service nginx restart

Any questions, let me know!