🌐 Detecting your location…

كيفية إنشاء تطبيق في الوقت الفعلي باستخدام Next.js وSupabase في عام 2026

⏱️3 min read  ·  536 words

سوباباس يوفر قاعدة بيانات PostgreSQL، والمصادقة، والاشتراكات في الوقت الفعلي كواجهة خلفية مُدارة – الاقتران بشكل مثالي معNext.js لبناء تطبيقات كاملة في الوقت الفعلي بسرعة. ينشئ هذا الدليل تطبيقًا في الوقت الفعلي بدءًا من قاعدة البيانات وحتى النشر.

لماذا Next.js + Supabase؟

  • الواجهة الخلفية الكاملة بدون إنشاء واحدة: قاعدة البيانات، والمصادقة، والتخزين، وفي الوقت الحقيقي خارج الصندوق
  • PostgreSQL الحقيقي: ليست قاعدة بيانات خاصة — SQL قياسي يمكنك الاستعلام عنه مباشرة
  • الاشتراكات في الوقت الحقيقي: استمع إلى تغييرات قاعدة البيانات مباشرةً باستخدام الحد الأدنى من التعليمات البرمجية
  • المصادقة المضمنة: البريد الإلكتروني وOAuth والروابط السحرية – لا توجد بنية أساسية للمصادقة لإنشاء
  • مفتوح المصدر: استضافة ذاتية، وتجنب تقييد البائع

الإعداد

npx create-next-app@latest my-app
cd my-app
npm install @supabase/supabase-js @supabase/ssr
# Create a project at supabase.com, then add to .env.local
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key

إعداد عميل Supabase

// lib/supabase.js
import { createClient } from '@supabase/supabase-js';

export const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
);

إنشاء جدول (محرر SQL في Supabase)

-- Create a messages table
create table messages (
  id uuid default gen_random_uuid() primary key,
  content text not null,
  user_id uuid references auth.users,
  created_at timestamptz default now()
);

-- Enable Row Level Security
alter table messages enable row level security;

-- Policy: anyone can read messages
create policy "Messages are viewable by everyone"
  on messages for select using (true);

-- Policy: authenticated users can insert their own messages
create policy "Users can insert their own messages"
  on messages for insert
  with check (auth.uid() = user_id);

الاشتراكات في الوقت الحقيقي

// components/Chat.jsx
'use client';
import { useState, useEffect } from 'react';
import { supabase } from '@/lib/supabase';

export default function Chat() {
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    // Load existing messages
    supabase.from('messages').select('*').order('created_at')
      .then(({ data }) => setMessages(data || []));

    // Subscribe to new messages in real time
    const channel = supabase
      .channel('messages')
      .on('postgres_changes',
        { event: 'INSERT', schema: 'public', table: 'messages' },
        (payload) => {
          setMessages(prev => [...prev, payload.new]);
        }
      )
      .subscribe();

    // Cleanup subscription
    return () => { supabase.removeChannel(channel); };
  }, []);

  const sendMessage = async (content) => {
    const { data: { user } } = await supabase.auth.getUser();
    await supabase.from('messages').insert({ content, user_id: user.id });
  };

  return (
    <div>
      {messages.map(m => <div key={m.id}>{m.content}</div>)}
    </div>
  );
}

المصادقة

// Sign up
async function signUp(email, password) {
  const { data, error } = await supabase.auth.signUp({ email, password });
  if (error) throw error;
  return data;
}

// Sign in
async function signIn(email, password) {
  const { data, error } = await supabase.auth.signInWithPassword({ email, password });
  if (error) throw error;
  return data;
}

// OAuth (Google, GitHub, etc.)
async function signInWithGitHub() {
  await supabase.auth.signInWithOAuth({ provider: 'github' });
}

// Get current user
const { data: { user } } = await supabase.auth.getUser();

// Sign out
await supabase.auth.signOut();

مكونات الخادم وجلب البيانات

// app/page.jsx - Server Component fetching data
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';

export default async function Page() {
  const cookieStore = cookies();
  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
    { cookies: { get: (name) => cookieStore.get(name)?.value } }
  );

  const { data: messages } = await supabase
    .from('messages')
    .select('*')
    .order('created_at', { ascending: false })
    .limit(20);

  return <MessageList initialMessages={messages} />;
}

الأمان على مستوى الصف: مفتاح البيانات الآمنة

يستخدم Supabase أمان مستوى صف PostgreSQL (RLS) للتحكم في الوصول إلى البيانات. نظرًا لأن العميل يتصل مباشرة بالمفتاح المجهول، فإن سياسات RLS هي التي تحافظ على أمان البيانات – فهي تحدد من يمكنه قراءة/كتابة ماذا. قم دائمًا بتمكين RLS على جداولك واكتب السياسات. بدون RLS، يتم كشف البيانات الخاصة بك. إن خدمة RLS ليست اختيارية للإنتاج — فهي الأساس الأمني لنموذج العميل المباشر.

النشر

# Deploy to Vercel (seamless with Next.js)
# 1. Push to GitHub
# 2. Import the repo in Vercel
# 3. Add environment variables (NEXT_PUBLIC_SUPABASE_URL, ANON_KEY)
# 4. Deploy

# Supabase is already hosted - no backend deployment needed.
# Your Next.js frontend on Vercel + Supabase backend = full-stack app live.

الأسئلة المتداولة

س: هل Supabase بديل جيد لبناء الواجهة الخلفية الخاصة بي؟
ج: نعم، بالنسبة للعديد من التطبيقات – فهي توفر قاعدة بيانات PostgreSQL حقيقية ومصادقة وتخزينًا وفي الوقت الفعلي دون إنشاء بنية أساسية خلفية. تحصل على لغة SQL قياسية (وليست قاعدة بيانات خاصة)، لذلك لا تكون مقيدًا. إنها ممتازة للتطوير السريع للمكدس الكامل وأفضل اللاعبين.

س: كيف يعمل الوقت الحقيقي في Supabase؟
ج: يستمع Supabase إلى تغييرات PostgreSQL ويدفعها إلى العملاء المشتركين عبر WebSockets. أنت تشترك في أحداث INSERT/UPDATE/DELETE على الجدول، ويتم تشغيل رد الاتصال الخاص بك عندما تتغير البيانات. يمنحك الحد الأدنى من التعليمات البرمجية تحديثات مباشرة، وهو أمر رائع للدردشة والإشعارات والميزات التعاونية.

س: هل من الآمن استخدام Supabase مباشرة من العميل؟
ج: نعم، إذا كنت تستخدم أمان مستوى الصف (RLS). نظرًا لأن العميل يتصل بالمفتاح المجهول، فإن سياسات RLS تتحكم في ما يمكن لكل مستخدم قراءته/كتابته. قم دائمًا بتمكين خدمة RLS وكتابة السياسات – فهي أساس الأمان. بدون RLS، يتم كشف البيانات الخاصة بك. لا تخطيها أبدًا في الإنتاج.

س: Supabase أو Firebase؟
ج: يستخدم Supabase PostgreSQL (SQL قياسي، علائقي، غير قابل للقفل) وهو مفتوح المصدر/قابل للاستضافة الذاتية. يستخدم Firebase قاعدة بيانات NoSQL خاصة. اختر Supabase إذا كنت تفضل SQL والبيانات العلائقية وتجنب القفل؛ Firebase لنظامه البيئي الناضج وما إذا كان NoSQL يناسب بياناتك. كلاهما يقدم المصادقة وفي الوقت الحقيقي.

س: هل يمكنني استضافة Supabase ذاتيًا؟
ج: نعم — Supabase مفتوح المصدر ويمكن استضافته ذاتيًا، لتجنب تقييد البائع. يبدأ معظمها بالسحابة المُدارة (طبقة مجانية سخية) ويمكنها الاستضافة الذاتية لاحقًا إذا لزم الأمر. يعد خيار الاستضافة الذاتية ميزة رئيسية مقارنة بالبدائل المغلقة.

الخلاصة

Next.js + Supabase هي طريقة قوية وسريعة لإنشاء تطبيقات كاملة في الوقت الفعلي في عام 2026. يوفر Supabaseقاعدة بيانات PostgreSQL حقيقية، ومصادقة مضمنة، واشتراكات في الوقت الفعلي – الاقتران بسلاسة مع Next.js. سير العمل: إنشاء جداول باستخدام SQL، وتمكين أمان مستوى الصف من خلال السياسات (أمر بالغ الأهمية للوصول الآمن المباشر للعميل)، والاشتراك في التغييرات في الوقت الفعلي، واستخدام مصادقة Supabase للمستخدمين. انشر واجهة Next.js الأمامية على Vercel، وبما أن Supabase مستضاف بالفعل، فلديك تطبيق كامل مكدس مباشر بدون بنية أساسية خلفية لإدارته. قاعدة الأمان الأساسية هي تمكين RLS دائمًا – وهو ما يحافظ على أمان بياناتك التي يتم الوصول إليها مباشرة. بالنسبة للدردشة والأدوات التعاونية ولوحات المعلومات وMVPs، تتيح لك هذه المجموعة إنشاء تطبيقات كاملة في الوقت الفعلي بسرعة ملحوظة دون إنشاء واجهة خلفية أو إدارتها.

MD Rafikul Islam

Written by

MD Rafikul Islam is a software developer and the editor of TechPulse. He writes about developer tooling, hardware, and the practical decisions that come up in day-to-day engineering work — which laptop to buy, which framework to commit to, why a build broke at 2am. He tests the tools he writes about and says plainly when something is not worth the money. Corrections and corrections requests are welcome at rony.yf25@gmail.com.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা