NahdaAIنهضة
Supabase • المستوى الثالث • الدرس 4

المزامنة الفورية (Supabase Realtime)

العودة لفهرس المستوى

أهداف الدرس

  • الاشتراك في تغييرات قاعدة البيانات بـ channel().on().subscribe().
  • استقبال الأحداث: INSERT, UPDATE, DELETE.
  • إدارة القنوات وإلغاء الاشتراك.
  • بناء تطبيقات دردشة فورية.

1. ما هو Supabase Realtime؟

Supabase Realtime يسمح لك بالاستماع لتغييرات قاعدة البيانات (INSERT / UPDATE / DELETE) في الوقت الفعلي عبر WebSockets. مبني على ميزة Postgres Logical Replication.

  • • Channel — قناة الاتصال (يمكنك إنشاء قنوات متعددة).
  • • postgres_changes — نوع الاشتراك (تغييرات PostgreSQL).
  • • Payload — البيانات المُرسلة (new / old / eventType).
javascript
// بنية الاشتراك
const channel = supabase
  .channel('my-channel')              // 1. إنشاء قناة
  .on('postgres_changes', { ... },    // 2. الاستماع
      (payload) => { ... })
  .subscribe();                        // 3. تفعيل

// لإلغاء الاشتراك لاحقاً:
supabase.removeChannel(channel);

2. تفعيل Realtime على الجدول

خطوة إلزامية: قبل أن يعمل Realtime، يجب تفعيله على الجدول:

من Supabase Dashboard
  1. اذهب إلى Database → Replication
  2. اختر الجدول (مثل messages)
  3. فعّل INSERT, UPDATE, DELETE
  4. أو استخدم SQL أدناه
sql
-- تفعيل Realtime على جدول messages
ALTER PUBLICATION supabase_realtime ADD TABLE messages;

-- تحقق من الجداول المُفعّلة
SELECT * FROM pg_publication_tables
WHERE pubname = 'supabase_realtime';

3. أنواع الأحداث — event

يمكنك الاستماع لأحداث محددة أو لكل الأحداث:

INSERT

عند إضافة صف جديد.

{
  event: 'INSERT',
  schema: 'public',
  table: 'messages'
}
UPDATE

عند تعديل صف.

{
  event: 'UPDATE',
  schema: 'public',
  table: 'messages'
}
DELETE

عند حذف صف.

{
  event: 'DELETE',
  schema: 'public',
  table: 'messages'
}
* (الكل)

كل الأحداث.

{
  event: '*',
  schema: 'public',
  table: 'messages'
}

4. بنية Payload — ما يُرسَل إليك

عندما يحدث حدث، يُرسَل إليك payload يحتوي على:

javascript
// بنية payload
{
  eventType: 'INSERT',       // نوع الحدث
  schema: 'public',          // الـ schema
  table: 'messages',         // الجدول
  new: {                     // الصف الجديد (INSERT/UPDATE)
    id: 1,
    content: 'مرحباً',
    user_id: '...',
    created_at: '2024-...'
  },
  old: {},                   // الصف القديم (UPDATE/DELETE)
  commit_timestamp: '2024-...',
  errors: null
}

// للـ INSERT: استخدم payload.new
// للـ UPDATE: استخدم payload.new + payload.old
// للـ DELETE: استخدم payload.old

5. الفلترة والـ Status

يمكنك فلترة الأحداث بشروط، ومراقبة حالة الاشتراك:

javascript
// فلترة: فقط الرسائل في غرفة معينة
const channel = supabase
  .channel('room-1-messages')
  .on('postgres_changes',
    {
      event: 'INSERT',
      schema: 'public',
      table: 'messages',
      filter: 'room_id=eq.room-1'
    },
    (payload) => console.log('رسالة في room-1:', payload.new)
  )
  .subscribe((status) => {
    console.log('حالة الاشتراك:', status);
    // SUBSCRIBED / TIMED_OUT / CLOSED / CHANNEL_ERROR
  });

// يجب تفعيل filter في Dashboard أولاً

6. إدارة القنوات — removeChannel

بعد الاستخدام، يجب إلغاء الاشتراك لمنع تسرب الذاكرة:

javascript
// إلغاء قناة واحدة
const channel = subscribeToMessages(...);
supabase.removeChannel(channel);

// إلغاء كل القنوات (مفيد عند unmount)
supabase.removeAllChannels();

// في React:
useEffect(() => {
  const channel = subscribeToMessages(...);
  return () => {
    supabase.removeChannel(channel);
  };
}, []);
التطبيق العملي

تحدي الدرس: نظام دردشة فوري

  1. أضف subscribeToAllChanges لجميع الأحداث.
  2. أضف subscribeToUpdates للتحديثات.
  3. أضف subscribeToDeletes للحذف.
  4. أضف unsubscribe مع removeChannel.
  5. أضف اختباراً تلقائياً.
⏳ جارٍ التحميل...