
Supabase Realtimeを利用してチャットアプリやダッシュボードの共同編集、通知機能を構築している開発者にとって、購読フィルタの柔軟性とデータ転送量の削減は重要なテーマです。
これまでのSupabase Realtime(Postgres Changes)では、フィルタ条件を1つのカラムにしか指定できず、複数条件での絞り込みを行いたい場合は全件を受信してからフロントエンド側で不要なイベントを破棄する必要がありました。また、テーブル更新時にはレコード全体の全カラムがペイロードに含まれるため、通信量が増加しやすいという課題がありました。
今回のアップデートにより、Postgres Changesで複数カラムを組み合わせたANDフィルタ、カラム選択(select)、および like や is などの拡張演算子が正式にサポートされました。
この記事では、新しく追加されたフィルタ機能とカラム選択の具体的な設定手順、実装コード例、そして通信量やコスト削減への影響について詳しく解説します。
この記事で行うこと
前提条件・対象読者
注意点
新機能を利用するにあたり、以下の制限事項と仕様を事前に把握しておく必要があります。
アップデートの概要と旧仕様との比較
これまでの仕様と今回のアップデート内容の違いを整理します。
1. 複数カラムのANDフィルタ対応
従来は1カラムのみの指定(例: status=eq.open)に制限されていたため、特定チームに割り当てられたオープンチケットだけを購読したい場合でも、すべてのオープンチケットを受信してアプリ側で if (payload.new.team_id !== myTeamId) のように間引く必要がありました。 新仕様では、カンマ区切りまたは専用ビルダーにより複数条件をAND結合してサーバー側で正確にフィルタリングできます。
2. カラム選択(select)によるペイロード削減
従来はレコードの変更時に、テーブル内のすべてのカラム値がWebSocket経由で送信されていました。 新仕様では select: ['id', 'title', 'updated_at'] のように必要なカラムだけを指定でき、不要なカラム(大容量のテキストやバイナリ、センシティブなメタデータなど)をサーバー側で除外して受信できます。なお、指定を省略した場合はPrimary Keyのみが常に含まれます。
3. 利用可能な演算子の拡充
従来の単純な一致・比較に加え、パターンマッチの like や ilike、null判定の is、NULL安全な不一致判定 isdistinct、正規表現マッチ match や imatch、そして否定を表す not. 接頭辞が利用可能になりました。
手順1:クライアントライブラリを最新版に更新する
カラム選択オプションを使用するには、@supabase/supabase-js がバージョン 2.109.0 以上である必要があります。プロジェクトのパッケージを最新化します。
npmを使用する場合のコマンドは以下の通りです。
npm install @supabase/supabase-js@latest
package.json でバージョンが 2.109.0 以上になっていることを確認してください。なお、カラム選択を行わずANDフィルタや新演算子のみを利用する場合は、既存バージョンのライブラリのままでも動作します。
手順2:複数カラムのANDフィルタを実装する
複数カラムを条件に指定する場合、文字列によるカンマ区切り形式、または新設されたビルダー関数のいずれかを使用できます。
カンマ区切り文字列で指定する場合
フィルタ文字列の中で条件をカンマ(,)で区切ることで、すべての条件に一致するイベントのみを受信します。
import { createClient } from '@supabase/supabase-js'
const supabase = createClient('https://your-project.supabase.co', 'your-anon-key')
const channel = supabase
.channel('billing-tickets')
.on(
'postgres_changes',
{
event: 'UPDATE',
schema: 'public',
table: 'tickets',
filter: 'status=eq.open,team=eq.billing',
},
(payload) => {
console.log('課金チームの未完了チケットが更新されました:', payload)
}
)
.subscribe()
postgresChangesFilterビルダーを使用する場合
型安全性や可読性を重視する場合は、@supabase/supabase-js からインポートできる postgresChangesFilter() ビルダー関数を使用したメソッドチェーン形式が便利です。
import { createClient, postgresChangesFilter } from '@supabase/supabase-js'
const supabase = createClient('https://your-project.supabase.co', 'your-anon-key')
const channel = supabase
.channel('priority-tickets')
.on(
'postgres_changes',
{
event: 'INSERT',
schema: 'public',
table: 'tickets',
filter: postgresChangesFilter()
.eq('status', 'open')
.gte('priority', 3),
},
(payload) => {
console.log('優先度3以上の新規チケット:', payload)
}
)
.subscribe()
チェーンされた条件はすべてAND条件として結合されます。普段Supabaseのクエリビルダーで書き慣れている記法と近い感覚で購読条件を組み立てられます。
手順3:カラム選択(select)を指定して受信データを絞り込む
画面表示に必要なカラムだけを指定することで、受信するJSONペイロードのサイズを小さく抑えられます。
import { createClient } from '@supabase/supabase-js'
const supabase = createClient('https://your-project.supabase.co', 'your-anon-key')
const channel = supabase
.channel('ticket-list-summary')
.on(
'postgres_changes',
{
event: '*',
schema: 'public',
table: 'tickets',
filter: 'status=not.eq.archived',
select: ['id', 'subject', 'updated_at'],
},
(payload) => {
console.log('チケット要約ペイロード:', payload.new)
// payload.new には id, subject, updated_at のみが含まれます
}
)
.subscribe()
既存の購読コードに対して select オプションを追加しない限りは、従来通りレコード全体の全カラムが届くため、既存の実装を壊さずに段階的に導入できます。
手順4:新しく追加された演算子を活用する
文字列の部分一致やnullチェック、否定条件など、これまで対応していなかった条件指定を試してみましょう。
import { createClient } from '@supabase/supabase-js'
const supabase = createClient('https://your-project.supabase.co', 'your-anon-key')
// 特定ドメインのメールアドレスに限定(like)
const userChannel = supabase
.channel('company-users')
.on(
'postgres_changes',
{
event: 'INSERT',
schema: 'public',
table: 'users',
filter: 'email=like.%@example.com',
},
(payload) => console.log('社内ユーザー登録:', payload)
)
.subscribe()
// 論理削除されていないレコードに限定(is.null)
const activeRecords = supabase
.channel('active-items')
.on(
'postgres_changes',
{
event: 'UPDATE',
schema: 'public',
table: 'items',
filter: 'deleted_at=is.null',
},
(payload) => console.log('有効アイテム更新:', payload)
)
.subscribe()
// 特定ステータス以外を除外(not.eq)
const inProgressTasks = supabase
.channel('tasks')
.on(
'postgres_changes',
{
event: 'UPDATE',
schema: 'public',
table: 'tasks',
filter: 'status=not.eq.archived',
},
(payload) => console.log('アーカイブ以外のタスク更新:', payload)
)
.subscribe()
通信量とコストへの好影響
Supabase Realtimeは、送信されたメッセージ数およびEgress(アウトバウンドデータ転送量)に基づいて課金が計算されます。
データベースで1行が更新された際、そのテーブルを購読しているクライアントの数だけメッセージが配信されます。 サーバー側のANDフィルタによって不要なイベントが拒否されると、クライアントへの配信メッセージ数が減少し、Realtimeのメッセージクォータ消費を直接抑制できます。
さらに、select オプションで不要なカラム(本文データやログ情報など)を削ることで、1メッセージあたりのデータサイズが小さくなり、Egress転送量の削減に繋がります。高トラフィックなサービスやモバイルアプリにおいて、通信コストと端末バッテリー消費の両面で大きなメリットとなります。
うまくいかない場合の確認ポイント
設定後にイベントが届かない、または想定外のデータが届く場合は以下を確認してください。
よくある質問
Q. OR条件(いずれかの条件に一致)は使えますか? A. 今回のリリースではAND条件のみがサポートされています。OR条件による購読を行いたい場合は、別々のチャンネルとして購読するか、従来通りアプリ側で判定する必要があります。
Q. 既存の購読コードは書き直す必要がありますか? A. いいえ、既存のコードはそのまま動作し続けます。ANDフィルタやカラム選択を明示的に指定したチャンネルのみ挙動が変更されます。
Q. カラム選択にPrimary Keyを含めなかった場合はどうなりますか? A. select 配列にPrimary Keyを含め忘れた場合でも、レコードを識別するためにPrimary Keyは自動的にペイロードへ含まれます。
まとめ
Supabase RealtimeのPostgres Changesに追加された新機能により、リアルタイムイベントの購読精度が向上し、無駄なメッセージ送信とデータ転送量を大幅に削減できるようになりました。
リアルタイム通信のコストやモバイル端末の負荷に悩んでいたプロジェクトは、ぜひ @supabase/supabase-js を更新して導入してみてください。
次に読むおすすめ記事


