Blog

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.

How To Extract The Audio From A YouTube Video In MP3 Format

There are a lot of songs on YouTube. To make a copy of just the audio of a video on your computer, follow these steps:

  1. Install youtube-dl. If you’re using a mac and use Homebrew, you can simply type brew install youtube-dl
  2. Then from the command line, type youtube-dl --extract-audio --audio-format mp3 <video URL>

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 myip.opendns.com @resolver1.opendns.com
  • curl icanhazip.com (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.

How to call Freshbooks Classic directly in Node.js using axios

I was using the freshbooks npm module, but started having issues with its dependencies as it was last updated 3 years ago.

It turns out even though the payloads are in XML, it’s not too bad calling their classic API directly once you know how. Of course, then you need to process an XML response. But instead of having to use an XML library, since I know what specific fragment of data I want, I can use regular expressions to extract it.

So here is a code sample on how to call their API directly

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 Convert a JavaScript Object To A Query String

Let’s say you have a lot of query parameters you need to add to an Ajax request. For code maintainability, it’s much cleaner to create a large JavaScript object, use string interpolation for the URL, and then adding a function that converts the JavaScript object to a query string.

This is what it might look like…

How to programatically extract YouTube captions as plain text

YouTube automatically creates subtitles for a lot of videos that are uploaded to YouTube.

So instead of paying to have your videos transcribed, you can upload your video to YouTube, and programatically download the subtitles.

But it took me a while to figure out how to get those subtitles programatically.

I started with youtube-dl, but I could only get the WebVTT format which is cumbersome to post-process. I posted an issue in their GitHub repo.

I finally found a little npm library someone had built that made this task fairly straight forward. Here is a code sample that will take a YouTube URL as a command line argument, and then log the subtitles as plain text.

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).

Type..

gpg2 -e -a -s -r support@andrewgolightly.com 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

-----BEGIN PGP MESSAGE-----

hQEMA4ZIL4znZiEXAQgAnbrsoC3GkeDQAKoJOVPEGcxET5SRkWuF7v7zO5ND1cp6
qlabecjdqsSmxSsHjAMdyvCGBfQXMEbNnqmxHmB5YMA79bS/TbQQYEx6xv9EBJfu
7aU/vjTxVSDA9ySbscptTbSGWbJG7dOa2RkAvbgjF5D7OYaRvVZP+9KuI4D3O0PI
m80Kxl4DeY+UTvgian3cfGiBKTTWcl9diBkHvGBIVC8NGHt/+htVXbDxLIvmU4vK
+HEWBqqA/HZqD5jTT4nqER65nQaCibZ0oouAUy5vcdQaOcwRhsFdjVTu5vobnXUP
K2TfFNrt9izqzCWPjBcD8bzCUFvu54t+03NIJUXg4tLpAaeMB9k66R0gbKzb7bGy
ibW2hyHhX3N0a2gyvN+/PzgNiEuwhgOOrZyl4XqVy+E3uzMXk3kDmdUCbqv44vxq
6+HSfNfRqHyAZ4XaQ6BXdCteClkMPHteAOv39MczKXSFMMEG7VojYuZ7DxQVjFrc
KNZEnOCjmAVZK3bIJwEgXTWuC0uN4ZyHPS3UUS20rYlwdQBXgW5SS4FkX/omzY1r
ptFhZ3xJ3MSp3Bh+MS4jPWTgnnjkh9uXcFSvGoCdtyWVr3fAjbUro4JIbePiTbTI
mci181SgS9xXVv+yp0QdiHhBFwGGXRWr45r3S36VN3UzYjPtqfYkbNGMWIYnmbqY
GjMwlhUPNwb6eZAI/iE8uQynLT6WklLmpdBgbZ0lDIU6gWGprZ1Ayhj3sPcMoux2
EIELLWjyk0EKgQIK6BGnvEsBAZPHYZJTr+RVbZFWjRKNzf3RfPHm8mJRnvAPTq+b
gjMv4GCuGwVNwU7NGJPTl2MVLFILjg4PlSFy0tzNagk7wmggaLsk/vsRZmPB5LzJ
H4V4sji5iH4sxFDO74/88Bt234rTlQT7cOwiEGFF9ScE62K/8LlyhEXfyuuFG1k4
rpZy6XmqVrKa4ogh51OR6Jl93Ke3xbrbAzkHfO2TBHiFEqdGeIrrEkgxmVeftigY
xsva+zTCmGc7JKGKmDWeXM/AeTy32ZKJEbbX/rjkjnmJSUf1PVd+xupXsPD6yy+p
DLJ4HleW0Fj9pbJM2Gsq8vMRt01BrEJd9VRfOZriqUY1CbC6ZF2Y3yUajlKV8Haj
88wQPD48MMuqIH5x8DtVwsK0ZSlssEtZS56pwNR11J8N4y7tDeKUR4e8yneTQ22L
PhCLqE2G2zUcJCd5Rg0UHSAy/Ko37PARWy+JErHgu7QKkLkWkUus8fIEgUR6Wc05
T2p1YYDx56bXCu/zqABrzWnBHTWDbCNUytpwdlJPgUa+YLkLFtuKX4FSAM2q5D+q
TuLLzan5gqUKemzOVRymPNyTH+XD/TkCZ9urMManTjpRP4JBrx+sZW6tFY6P958M
FLNwddt7giEhiYIXfQYEW1Qu0VH3cekjW95purRbauHu2A7g5f7Q71+1cFc=
=TCNH
-----END PGP MESSAGE-----

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

node_modules/
config/*.json
config/*.js

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 ag-gnupg.zip 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.