Bank: Integrating push notifications

After a fair period of doing research into the industry and various technical considerations, development work on the banking project has started once more.

On the to-do list for some time now was push notifications. This is an interesting one as it affects both the server and the client and both are closely tied together.

Backend structure

I decided to add a separate table for the token storage. This table links tokens to an account, holds the token value, and also holds the platform the token is for. This allows a user to have multiple devices registered against his account, and have notifications sent to all of them. For now, this is the default but users will be able to remove these devices individually, as well as more extended functionality.

I added an API route for the creation and deletion of push tokens. The format is pretty simple, one of the route handlers is seen below:

func AccountTokenPost(w http.ResponseWriter, r *http.Request) {
	token, err := getTokenFromHeader(w, r)
	if err != nil {
		Response("", err, w, r)
		return
	}

	pushToken := r.FormValue("PushToken")
	platform := r.FormValue("Platform")

	response, err := accounts.ProcessAccount([]string{token, "acmt", "1003", pushToken, platform})
	Response(response, err, w, r)
	return
}

Push in Go

I decided to use a fairly well known apns library which simplifies the entire process. I’ve had some previous success around sending push notifications to my application from the CLI so had confidence going in.

For the implementation, a separate sub-package was added in the same style of the rest of the application. This package currently has two functions which just send a notification when given some information. The package is available to view here for those interested in more detail.

The sending of the push notifications is currently done on two events: sending payments and receiving payments. This results in three calls, one each for the sender and recipient on a payment, and one for the receipient on a deposit. Due to the abstract push package, the notification is called simply:

go push.SendNotification(receiver.AccountNumber, "💸 Payment received!", 5, "default")

A note on push notification detail

Many financial applications send sensitive information over channels they do not control - SMS, Email, and Apple push/GCM being some examples. I deliberately excluded these details with the assumption that these channels are compromised from the start.

This does not reduce the functionality though. As soon as the notifications are received, the application will do a call and find the relevant data, displaying this to the user when they have authenticated in the app.

Technology has outpaced security, and as such this project has a major focus on fixing those security holes. This will be done both through the use of strong cryptography, as well as through best practices like the example above.

React Native push

React has a pretty neat way of making push work nicely, and by including a package react-native-push-notification I was almost the whole way there. This package exposes a method onNotification which is used when something is received, and after doing the initial hooks you are good to go.

I decided to use the local Realm DB to store the token along with the platform (this application is one codebase for both platforms). This information is then pulled out and sent to the API on every sign in. Due to the abstracted API client the call is simple after fetching all the relevant data from the store. The code is here.

There is still a bunch of work to do around this, like listing the notifications, clearing them on being read, having different types (activity vs security alert), etc. I’ll be putting love into this project and shaping it into something nice.

Conclusion

There’s been some good progress on the push front, I’ll get to testing this when some of the smaller issues are resolved. iOS push is a nightmare to debug, but where there is a will.

Some really exciting stuff is coming up for the project in the next few months, including a rebrand, real scoping of the mobile application, a look at a desktop application (for the core banking administrators) and more! I’m also speaking to some of the bigger financial bodies about getting access and enquiring about standards so will fold those developments in as I get clarity.

As always, all code is on Github. The server and the client. Feel free to jump in and tackle an issue or two 🎉