RORK LABJP
TOOLING — Rork's developer repos keep moving: rork-xcode was updated on July 16, rork-device on July 15, and rork-plist on July 13OPUS46 — Claude Opus 4.6 is live in Rork, and Rork Max is built to assemble apps on top of Claude CodeSIM — A cloud iOS simulator runs in the browser, with one click to install on a device and two clicks to publish to the App StoreMAX — Rork Max emits pure Swift rather than React Native, reaching iPhone, iPad, Apple Watch, Apple TV, Vision Pro, and even iMessageNATIVE — That opens up HealthKit, ARKit and LiDAR, NFC, Dynamic Island, Live Activities, 3D through Metal, and on-device inference with Core MLSEED — Rork raised a $15M seed led by Left Lane Capital, with Peak XV and a16z Speedrun joining the roundTOOLING — Rork's developer repos keep moving: rork-xcode was updated on July 16, rork-device on July 15, and rork-plist on July 13OPUS46 — Claude Opus 4.6 is live in Rork, and Rork Max is built to assemble apps on top of Claude CodeSIM — A cloud iOS simulator runs in the browser, with one click to install on a device and two clicks to publish to the App StoreMAX — Rork Max emits pure Swift rather than React Native, reaching iPhone, iPad, Apple Watch, Apple TV, Vision Pro, and even iMessageNATIVE — That opens up HealthKit, ARKit and LiDAR, NFC, Dynamic Island, Live Activities, 3D through Metal, and on-device inference with Core MLSEED — Rork raised a $15M seed led by Left Lane Capital, with Peak XV and a16z Speedrun joining the round
Articles/Dev Tools
Dev Tools/2026-03-29Advanced

Push Notification Masterplan for Rork Apps — Segmented Delivery, A/B Testing, and Automation Pipelines

An advanced guide to push notifications in Rork apps. Learn how to implement user segmentation, A/B testing, automated lifecycle pipelines, and retention-focused delivery strategies.

Rork515push notifications11segmentationA/B testing4Firebase Cloud MessagingExpo Notificationsretention9automation7

Premium Article

Setup and context — Why "Blast Everyone" Doesn't Work Anymore

Push notifications are one of the most powerful retention channels available to mobile app developers. But sending the same message to every user at the same time is a recipe for notification fatigue, rising opt-out rates, and diminishing returns.

Look at any top-performing app on the App Store or Google Play, and you'll find they all rely on segmented delivery based on user behavior and attributes, A/B testing to optimize messaging and timing, and event-driven automation pipelines to keep everything running without manual intervention.

In this guide, we'll walk through the architecture and implementation patterns for running production-grade push notifications in a Rork (React Native / Expo) app. This is aimed at developers who already have basic push notifications working — if you haven't set that up yet, start with our push notification fundamentals guide first.

Designing a Segmentation System — Delivering the Right Message to the Right User

Segmentation Dimensions

Effective segmented delivery starts with defining how you classify your users. Here are the three dimensions that work best in practice.

Attribute-based segments classify users by static properties captured at registration — language, region, plan tier, and signup date. These are simple to implement but offer limited personalization.

Behavior-based segments classify users by in-app actions — last activity date, session frequency, feature usage counts, and purchase history. Because they reflect what users are actually doing, they enable far more targeted messaging.

Lifecycle segments classify users by engagement stage — new, active, inactive, at-risk, and churned. Tailoring messages to each stage is the single most impactful thing you can do for retention.

Segment Management Table Design with Supabase

Let's design the database schema for managing segment data. Here's a Supabase (PostgreSQL) implementation:

-- User segment management table
CREATE TABLE user_segments (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
  -- Attribute segments
  locale TEXT DEFAULT 'ja',
  plan_type TEXT DEFAULT 'free', -- free / pro / premium
  registered_at TIMESTAMPTZ NOT NULL,
  -- Behavioral segments
  last_active_at TIMESTAMPTZ,
  session_count INTEGER DEFAULT 0,
  feature_usage JSONB DEFAULT '{}',
  -- Lifecycle segment (auto-calculated)
  lifecycle_stage TEXT GENERATED ALWAYS AS (
    CASE
      WHEN last_active_at IS NULL THEN 'new'
      WHEN last_active_at > NOW() - INTERVAL '3 days' THEN 'active'
      WHEN last_active_at > NOW() - INTERVAL '14 days' THEN 'inactive'
      WHEN last_active_at > NOW() - INTERVAL '30 days' THEN 'at_risk'
      ELSE 'churned'
    END
  ) STORED,
  -- Notification preferences
  push_token TEXT,
  push_enabled BOOLEAN DEFAULT true,
  quiet_hours_start TIME DEFAULT '22:00',
  quiet_hours_end TIME DEFAULT '08:00',
  timezone TEXT DEFAULT 'Asia/Tokyo',
  updated_at TIMESTAMPTZ DEFAULT NOW()
);
 
-- Indexes for segment queries
CREATE INDEX idx_segments_lifecycle ON user_segments(lifecycle_stage);
CREATE INDEX idx_segments_plan ON user_segments(plan_type);
CREATE INDEX idx_segments_push ON user_segments(push_enabled) WHERE push_token IS NOT NULL;

The key design choice here is the lifecycle_stage column using PostgreSQL's GENERATED ALWAYS AS ... STORED. Whenever last_active_at is updated, the lifecycle stage is automatically recalculated. No application-side logic needed — the database always reflects the current state.

Tracking Segment Data from the Rork App

We need a hook that automatically records user activity and feeds the segment table in real time:

// hooks/useSegmentTracker.ts
import { useEffect, useCallback } from 'react';
import { AppState, AppStateStatus } from 'react-native';
import { supabase } from '@/lib/supabase';
import { useAuth } from '@/hooks/useAuth';
 
export function useSegmentTracker() {
  const { user } = useAuth();
 
  // Record a session whenever the app comes to foreground
  useEffect(() => {
    if (!user) return;
 
    const subscription = AppState.addEventListener(
      'change',
      (nextState: AppStateStatus) => {
        if (nextState === 'active') {
          updateActivity(user.id);
        }
      }
    );
 
    // Also record on initial mount
    updateActivity(user.id);
 
    return () => subscription.remove();
  }, [user]);
 
  const updateActivity = useCallback(async (userId: string) => {
    const { error } = await supabase
      .from('user_segments')
      .upsert(
        {
          user_id: userId,
          last_active_at: new Date().toISOString(),
          session_count: supabase.rpc('increment_session_count', {
            target_user_id: userId,
          }),
        },
        { onConflict: 'user_id' }
      );
 
    if (error) {
      console.warn('Segment update failed:', error.message);
    }
  }, []);
 
  // Helper to track individual feature usage
  const trackFeatureUsage = useCallback(
    async (featureName: string) => {
      if (!user) return;
 
      const { data: current } = await supabase
        .from('user_segments')
        .select('feature_usage')
        .eq('user_id', user.id)
        .single();
 
      const usage = (current?.feature_usage as Record<string, number>) || {};
      usage[featureName] = (usage[featureName] || 0) + 1;
 
      await supabase
        .from('user_segments')
        .update({ feature_usage: usage })
        .eq('user_id', user.id);
    },
    [user]
  );
 
  return { trackFeatureUsage };
}

Mount this hook in your app's root layout, and session data flows automatically into your segment table. Call trackFeatureUsage from specific screens or actions to build up per-feature usage counts.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
Real-world numbers from operating apps with 50M+ cumulative downloads — segment design and opt-out rates
Shared notification infrastructure patterns for running multiple apps in parallel, with CPS-controlled dispatch
Continuous KPI monitoring and the improvement loop using BigQuery + Looker Studio
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

Dev Tools2026-03-30
How to Automate Background Jobs in Rork Mobile Apps with Trigger.dev
Learn how to combine Trigger.dev with Rork-built mobile apps to automate background jobs like push notifications, data syncing, and content updates with practical TypeScript examples.
Dev Tools2026-06-25
When Push Notifications Reach Only Some Users — A Delivery-Reliability and Diagnosis Design for Rork (Expo) Apps
A design for diagnosing why push notifications reach only some users in a Rork-generated Expo app, by splitting send-to-display into stages and measuring delivery to close the gap. Covers stale-token cleanup, recording APNs/FCM failure codes, priority and message type, and a per-user triage procedure, with implementation.
Dev Tools2026-04-24
Cut First-Day Drop-off by Half — A Data-Driven Onboarding Design Note for Rork Apps
How do you actually lower the 24-hour drop-off on a Rork-built app? This is a working solo developer's notes — measurement funnel, onboarding cuts I made, and the weekly cadence I use to iterate.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →