1. Rowfire
  2. Use cases

Remind users who never confirmed their email

Send a Braze event when a Supabase user still hasn't confirmed their email a day after sign-up, once per user, read from auth.users with no app code.

  • Supabase
  • Braze
  • Any REST API
  • Growth
  • once per user

The trigger

One read-only SELECT against Supabase. Rowfire polls it for new rows, and the rule fires once per user.

SELECT u.id AS user_id,
       u.email,
       u.created_at AS signed_up_at,
       u.created_at + interval '24 hours' AS remind_at
FROM auth.users u
WHERE u.email_confirmed_at IS NULL
  AND u.email IS NOT NULL
  AND u.is_anonymous = false
  AND u.deleted_at IS NULL
  AND u.email NOT LIKE '%@yourcompany.example'

Someone signs up, gets the confirmation email, and never clicks it. Maybe it went to spam, maybe they got distracted. Your app doesn’t notice: no code runs when a link goes unclicked, so there is no event to send. The user is a row in auth.users with an empty email_confirmed_at, and a growth team that never hears about them.

The query finds them instead. It reads Supabase’s own auth.users table, named with its schema, since anything unqualified is read as public. The key is user_id and the clock is remind_at, a day after sign-up. When a poll sees remind_at pass for a user who still matches, the rule fires once per user, so nobody gets the same reminder twice.

The filters drop anonymous users, deleted users and your own team’s test sign-ups. The test domain is a placeholder; use the one your team signs up with.

The Braze side

Bind the Braze track_event action, with external_id set to {{ user_id }} (if that is how your app identifies users in Braze) and an event name like email_unconfirmed. A campaign triggered by that custom event sends the reminder, with a link back to your app where they can ask for a fresh confirmation email. signed_up_at can ride along as an event property.

Your own email service instead

If reminders go out through your own email service, add its API as an integration (base URL, auth, and the request body) and bind it to the same trigger. Any column in the row can go in the body as {{ email }} or {{ user_id }}. Each rule keeps its own count, so Braze and the email service can run side by side while you compare them.

A second nudge

Some teams send one more reminder after three days. That is a second trigger with interval '3 days' in place of interval '24 hours', and its own rule, also once per user. Users who confirm after the first reminder drop out of both.

Backtest each rule over the last few weeks to see how many users it would have reached, then run it in shadow before it goes live. For more on reading Supabase, see how to send Slack alerts from Supabase. For the next step in a new user’s life, see welcome users the first time they activate, or try a trigger on the live demo.

Questions

Does Rowfire need my Supabase database password to read auth.users?

No. It sends the query to Supabase's read-only query endpoint, which runs it as Supabase's read-only user. You connect with OAuth (Projects: Read and Database: Read) or a personal access token. Tables outside public, like auth.users, are named in the query.

What if the user confirms an hour before the reminder?

Then email_confirmed_at is set and the row no longer matches, so nothing fires. Only users still unconfirmed when remind_at passes are reminded.

Will everyone who never confirmed get a reminder when I switch it on?

No. The poller starts every trigger at now, so history never fires. A backtest shows what the rule would have sent over past days, without sending anything.

Does it change anything in Supabase?

No. Rowfire only reads. The query runs as Supabase's read-only user, and Rowfire's query checker refuses anything but a single SELECT.