Dan Ryland

"Stormzy uploaded an unreleased song" - Insidr Music notifications using Supabase & OneSignal

Picture your favourite music artist.

You pick up your phone and you have these notifications from that very artist:

Insidr notification

“Stormzy uploaded an unreleased song”

“Stormzy messaged you”

“Stormzy sent you a video”

Wouldn’t that be cool?

Well, it’s now possible.

How?

Insidr Music

Insidr is essentially OnlyFans for musicians, a direct-to-fan subscription platform for music artists.

Created by music artists for music artists - Yep, I’m a drummer!

Now, this is a story all about how my life got flipped-turned upside down …I built those sweet notifications.

Fresh Prince gif

Insidr has a beautifully simple stack: Supabase and Quasar.

For those who don’t know, Supabse is an open source Firebase alternative and Quasar is a cross-platform Vue.js framework that allows me to build a web app, iOS and Android app all from a single codebase.

I’ve been a fan of both for a while now.

But what about building more complex apps that need in-app purchases or notifications.

Quasar uses Capacitor (or Cordova) to deploy these native apps so for in-app purchases I use Glassfy

It’s an SDK that provides me with the subscription infrastructure I need for both iOS and Android.

As a first-timer for both in-app purchases and Glassy, I found implementing Glassy incredibly easy.

Now let’s talk about notifications.

Again, I’m a first-timer implementer here.

I knew what I wanted to achieve:

  • Fan subscribes to Artist
  • Artist uploads new music or posts an update
  • Based on the type of update, a custom notification gets sent to all their subscribed users

After some research, it seemed OneSignal had the best/clearest documentation for using it with Cordova/Capacitor.

I created my ‘push’ templates with a placeholder for the dynamic content, the artist’s name.

Notification templates

I added the OneSignal SDK to my app and pushed a test push notification via their dashboard to my iPhone.

import { boot } from "quasar/wrappers";
import OneSignal from "onesignal-cordova-plugin";
import { Platform } from "quasar";

export default boot(({ app, router }) => {
    router.isReady().then(() => {
        if (Platform.is.nativeMobile && Platform.is.ios) {
            OneSignal.initialize(process.env.ONESIGNAL_ID);
            OneSignal.Notifications.requestPermission();
        }
    });
});

Sweet success.

The test notification came through.

Test notification

Now to use their API to trigger a similar test push notification.

Once I knew the format required, I’d move this into a Supabase Edge Function so I could trigger it from an entry in the database and grab the name of the artist to populate the notification.

It took some work, but I managed to use Postman to trigger a dynamic notification by passing a template_id and the artist_name within a custom_data object.

Postman

I’m getting closer to the real thing.

So far I had worked out how to send dynamic notifications to all users, not just those subscribed to an artist.

Now how do I send notifications just to those who have subscribed?

Thankfully OneSignal has tags to help with this.

After some GPT-ing to help me flesh out the approach, I decided to add a subscribed_to_[ARTIST] for each subscription a fan has.

Once OneSignal is initialised, I passed Supabase’s user ID to connect the two profiles - the app user with the OneSignal profile of the user (their device).

OneSignal.login(user.id)

This allows me to add tags to their OneSignal profile using an external ID (Their user ID) I then looped through the user’s subscriptions and added a tag for each subscription they had:

artists.forEach((artist) => {
    OneSignal.User.addTag("subscribed_to_" + artist.slug, "true");
});

Back over to the API call, I added a filter which allowed me to only send specific notifications based on the users subscription:

filters: [
    {
        field: "tag",
        key: `subscribed_to_${artist_slug}`,
        relation: "=",
        value: "true",
    },
],

Now that this all worked well in Postman, I worked it into a Supabase Edge Function and added a query to get the artist’s name and slug from a given artist ID.

I needed this edge function to run across two tables: tracks and updates.

Now that Supabase has database webhooks, this meets my needs perfectly.

Webhooks allowed me to watch for inserts on two tables to trigger the same edge function.

Webhook config

I modified my edge function to add conditional logic based on which table the record was from (tracks or updates).

From there, I added more conditional logic based on the record data from the webhook to use a specific template.

For example, if it was the tracks table and the record has the ‘unreleased’ field marked as true then it would use a specific OneSingal template ID.

My function would also use the artist_id from the record to find the name and slug of the artist.

Brining this all together it dynamically built the payload needed for OneSignal to send the correct, dynamic notification.

const templates = {
    tracks: {
      released: "XXX-XXX",
      unreleased: "XXX-XXX",
    },
    updates: {
      image: "XXX-XXX",
      video: "XXX-XXX",
      audio: "XXX-XXX",
      message: "XXX-XXX",
    },
  };

  switch (body.table) {
    case "tracks":
      template_id = data.public
        ? templates.tracks[data.unreleased ? "unreleased" : "released"]
        : null;
      break;
    case "updates":
      template_id = data.image
        ? templates.updates.image
        : data.video
        ? templates.updates.video
        : data.audio
        ? templates.updates.audio
        : templates.updates.message;
      break;
  }

Satisfaction.

I created a new build of the iOS app, submitted it for review and got it approved.

I made an update in the database and hoped for the best.

Ping

Notification hits my iPhone.

Real notification

I’ve done it!

Now for all Insidr artists that upload new songs or post updates, their fans (their Insidrs) get notified.

Using Supabase Database Webhooks, Supabase Edge Function and OneSignal tags and API, I was able to make a pretty slick notifications system.

But my quest is not over.

Time to review the documentation for the Android implementation.

Wish this once ‘first-timer’ luck.

Music artist? Sign up for your Insidr

Until next time, keep hammering those nails.

Follow me on X/Twitter

Check out my Github