react-native-alarm-scheduler
API reference

Alarm occurrences

Resolve a ringing occurrence and optionally create a deferred or follow-up occurrence.

An alarm definition owns presentation, sound, repetition, and default metadata. An occurrence is one concrete native delivery of that definition. Keeping these identities separate lets an app defer an active alarm or schedule a later follow-up without rebuilding the native definition itself.

relationship describes how deliveries relate to one another. Optional metadata is stored and returned unchanged for application-defined context.

resolveAlarmOccurrenceAsync(occurrenceId, resolution)

Stops and resolves the active native occurrence, cancels stale recovery timers, preserves the alarm definition when needed, and optionally schedules the next occurrence as one library operation.

Defer an occurrence

const result = await AlarmScheduler.resolveAlarmOccurrenceAsync(occurrenceId, {
  outcome: 'deferred',
  next: {
    delaySeconds: 5 * 60,
    relationship: 'deferred',
  },
  idempotencyKey: `defer:${occurrenceId}:1`,
});

A deferred outcome must create a deferred next occurrence. The package preserves the alarm’s sound and presentation and overlays the supplied metadata on the definition metadata.

Complete with a follow-up

const result = await AlarmScheduler.resolveAlarmOccurrenceAsync(occurrenceId, {
  outcome: 'completed',
  next: {
    delaySeconds: 10 * 60,
    relationship: 'followUp',
  },
  idempotencyKey: `follow-up:${occurrenceId}`,
});

idempotencyKey is strongly recommended for UI actions. Retrying the same resolution returns its original result instead of creating another occurrence. The key is scoped to that concrete occurrenceId, so the same application key can safely be used for a later delivery of a repeating alarm.

Every primary firing receives a new persisted occurrenceId; the durable alarm definition keeps its original alarmId. Resolving or cancelling the current primary stops that delivery without removing the repeating schedule. A subsequent primary therefore has an independent lifecycle and cannot return an earlier delivery’s cached resolution.

The result status is resolved when the requested transition completed. It is resolvedWithoutNext when the current occurrence was resolved but the operating system rejected the requested next schedule. In that case nextOccurrence is absent.

getAlarmOccurrencesAsync(alarmId?)

Returns persisted occurrence records, newest first. Pass an alarm id to filter them.

type AlarmOccurrence = {
  occurrenceId: string;
  alarmId: string;
  parentOccurrenceId?: string;
  scheduledFor: number;
  relationship: 'primary' | 'deferred' | 'followUp';
  phase: 'scheduled' | 'ringing' | 'completed' | 'cancelled';
  metadata?: Record<string, string | number | boolean>;
};

Persist your product statistics separately. The occurrence record is the native source of truth for whether a delivery is scheduled, ringing, completed, or cancelled.

cancelAlarmOccurrenceAsync(occurrenceId)

Cancels one scheduled occurrence without cancelling its alarm definition or sibling occurrences. This is the appropriate operation when an app no longer needs a particular follow-up.

The method returns false if the occurrence is unknown or already completed/cancelled.

Current context

getCurrentAlarmContextAsync() includes occurrenceId and relationship when they are known. Its id remains the durable alarm id. On Android, a waiting deferred or follow-up occurrence is exposed as countdown; on iOS this maps naturally to the AlarmKit timer state.