Firebase Cloud Functions هي منصة خادم لتنفيذ الكود في بيئة Node.js مُدارة تستجيب لأحداث Firebase وطلبات HTTPS والتغييرات في خدمات Google السحابية. على عكس الخلفية التقليدية، لا يحتاج المطور إلى إعداد خادم أو تثبيت خادم ويب أو القلق بشأن التوسع — كل دالة تُنفذ في حاوية معزولة وتحصل تلقائياً على الموارد التي تحتاجها. وفقاً لـ Google Firebase (2026)، تعالج المنصة أكثر من 2 مليار استدعاء دالة يومياً، مما يوفر هندسة بدون خادم لملايين التطبيقات المحمولة.
النقاط الرئيسية
Firebase Cloud Functions هي منصة حوسبة مبنية على Google Cloud Functions (GCF)، ومُكيَّفة للنظام البيئي لـ Firebase. الدوال هي كود JavaScript أو TypeScript عادي يتم تصديره من وحدة وتسجيله لنوع حدث معين. عند حدوث حدث (على سبيل المثال، تسجيل مستخدم أو رفع ملف)، تقوم Firebase Cloud Functions بتشغيل الكود المقابل، مع تمرير سياق الحدث إليه.
هندسة Cloud Functions تتبع مبدأ المسؤولية الواحدة: دالة واحدة تعالج نوع حدث واحد وتؤدي عملية ذرية واحدة. على سبيل المثال، دالة sendWelcomeEmail تُستدعى عند إنشاء مستخدم جديد في Firebase Authentication وترسل بريداً ترحيبياً. هذا العزل يبسط التصحيح والاختبار وإعادة استخدام الدوال عبر مشاريع مختلفة.
كل دالة تُنفذ في حاوية معزولة بدورة حياة مؤقتة. الوقت الأقصى للتنفيذ افتراضياً هو 60 ثانية (دوال HTTPS — 9 دقائق). إذا لم تكتمل الدالة خلال المهلة، يفشل الطلب مع خطأ 500. للعمليات الطويلة، استخدم Cloud Tasks أو Pub/Sub مع إعادة المحاولة. يمكن إعادة استخدام الحاويات للاستدعاءات اللاحقة (keep-alive)، مما يقلل زمن الوصول في البدء البارد بعد الاستدعاء الأول.
Firebase Cloud Functions تدعم عدة إصدارات من Node.js: 18 و20 و22 (موصى به للمشاريع الجديدة). يُحدد الإصدار في حقل engines من ملف package.json. Firebase CLI يضبط بيئة التشغيل تلقائياً بناءً على الإصدار المحدد. من المهم: Firebase Cloud Functions لا تدعم تشغيل حاويات Docker عشوائية — البيئة محددة بدقة من Google Cloud Functions.
للمشاريع الجديدة، يُوصى باستخدام Node.js 22 لأنه يتضمن أحدث تحسينات V8 ودعماً محسّناً لوحدات ESM ودعم WebSocket على مستوى المنصة. إذا كان المشروع يستخدم تبعيات مبنية لإصدار Node محدد (مثل وحدات C++ أصلية)، يجب التحقق من التوافق بشكل فردي — ليست كل الوحدات الأصلية تُترجم تحت بيئة GCF.
Firebase Cloud Functions هي غلاف حول Google Cloud Functions مع Firebase SDK مثبت مسبقاً وتكامل مع خدمات Firebase. يكتب المطور الكود باستخدام SDK firebase-functions الذي يوفر مشغّلات مقولبة لجميع خدمات Firebase. Google Cloud Functions هي منصة ذات مستوى أقل حيث يتم تكوين المشغّلات عبر Eventarc أو Pub/Sub بشكل صريح.
الفرق الرئيسي: في Firebase Cloud Functions، يتم تسجيل المشغّل بشكل تصريحي عبر functions.firestore.document('path').onWrite()، بينما في Google Cloud Functions يتم تكوينه عبر Eventarc مع تصفية سمات الحدث. Firebase Cloud Functions يأتي أيضاً مع Admin SDK المهيأ تلقائياً ببيانات اعتماد حساب الخدمة للمشروع، مما يوفر وصولاً كاملاً لجميع خدمات Firebase دون إعداد إضافي.
Firebase Cloud Functions تدعم 8 فئات من المشغّلات، كل منها يتوافق مع خدمة محددة من Firebase أو Google Cloud. المشغّل هو شرط عند تحققه يتم استدعاء الدالة تلقائياً. المطور لا يدير دورة حياة الدالة مباشرة: Firebase CLI يسجل المشغّل في Google Cloud Eventarc، والمنصة السحابية تشغل الدالة عند حدوث الحدث.
أشهر المشغّلات هي مشغّلات Firestore: onWrite وonCreate وonUpdate وonDelete. يتم تفعيلها عند تغيير المستندات في مجموعات Firestore. تستلم الدالة لقطات للمستند قبل وبعد التغيير، مما يسمح بمقارنة القيم والاستجابة فقط لتغييرات محددة. على سبيل المثال، عندما تتغير حالة الطلب من “قيد الانتظار” إلى “تم الشحن”، يمكن إرسال إشعار دفع للمستخدم.
مشغّلات Authentication (onCreate، onDelete) يتم تفعيلها عند إنشاء أو حذف حساب مستخدم. تُستخدم لتهيئة بيانات المستخدم: إنشاء مستند مستخدم في Firestore، إرسال بريد ترحيبي، الكتابة في التحليلات. ملاحظة: لا يمكن للدالة إلغاء إنشاء المستخدم — يتم تنفيذها بعد أن يتم إنشاء الحساب بالفعل. للتحقق المسبق، استخدم Blocking Functions المتاحة على Identity Platform.
| فئة المشغّل | الحدث | مثال استخدام |
|---|---|---|
| Firestore | onWrite, onCreate, onUpdate, onDelete | تحديث عداد الإعجابات عند إضافة إعجاب |
| Authentication | onCreate, onDelete | إنشاء ملف تعريف مستخدم عند التسجيل |
| Realtime DB | onWrite, onCreate, onUpdate, onDelete | مراقبة الرسائل في الدردشة |
| Storage | onFinalize, onArchive, onDelete | إنشاء صورة مصغرة بعد رفع صورة |
| Pub/Sub | onPublish | تنفيذ مجدول (cron) عبر Cloud Scheduler |
| HTTPS | onRequest | نقطة نهاية REST API لخدمات خارجية |
دوال HTTPS (onRequest) تسمح بإنشاء نقاط نهاية REST API كاملة قابلة للوصول عبر HTTP. على عكس المشغّلات المستندة إلى الأحداث، تُستدعى دوال HTTPS عبر URL بالشكل https://{region}-{project}.cloudfunctions.net/{functionName}. من المهم تكوين CORS بشكل صحيح إذا تم استدعاء نقطة النهاية من متصفح أو تطبيق محمول. Firebase SDK لا يتضمن رؤوس CORS تلقائياً — يجب إضافتها يدوياً عبر middleware.
بالنسبة لـ العملاء المحمولين (Android، iOS)، CORS غير مطلوب لأن عملاء HTTP الأصليين غير مقيدين بسياسة Cross-Origin. CORS ذو صلة فقط بطلبات الويب. إذا كانت دالة HTTPS الخاصة بك تُستدعى من كل من التطبيق والويب، أضف معالجة CORS عالمية: res.set('Access-Control-Allow-Origin', '*') للتطوير أو قائمة بالنطاقات المسموح بها للإنتاج.
للـ تنفيذ الدوري (مهام cron)، استخدم مزيجاً من Cloud Scheduler وPub/Sub. Cloud Scheduler يرسل رسالة إلى موضوع Pub/Sub وفقاً لجدول زمني، ومشغّل onPublish في Cloud Functions يعالج تلك الرسالة. Firebase CLI لا يدعم بناء جملة cron مباشر — يتم ضبط الجدول عبر وحدة تحكم Google Cloud أو Terraform بتنسيق unix-cron: 0 3 * * * (كل يوم في الساعة 3:00).
أمثلة على المهام: النشرة البريدية اليومية، تنظيف البيانات القديمة، إنشاء التقارير، المزامنة مع APIs خارجية. مهم: Cloud Scheduler هي خدمة مدفوعة من Google Cloud (حوالي $2 شهرياً لكل وظيفة). كل تفعيل يُحتسب كاستدعاء دالة منفصل ويتم فوترته وفقاً لأسعار Cloud Functions القياسية.
تطوير Cloud Functions يبدأ بتهيئة مشروع عبر Firebase CLI: firebase init functions. هذا الأمر ينشئ دليلاً functions/ مع قالب index.js (أو index.ts) وملف package.json وتكوين TypeScript (إذا تم اختياره). بعد التهيئة، ببساطة اكتب دالة، قم بتصديرها من الوحدة، ونفذ firebase deploy --only functions للنشر.
كل دالة تُسجل باستدعاء طريقة المشغّل المناسبة. مثال لدالة HTTPS: exports.helloWorld = functions.https.onRequest((req, res) => { res.send(“Hello!”); }). دوال Firebase تستخدم نموذجاً غير متزامن: للمشغّلات المستندة إلى الأحداث (غير HTTPS)، يجب أن تعيد الدالة Promise. Firebase ينتظر إكمال Promise قبل إنهاء الحاوية. إذا لم تُعد Promise، قد يتم إنهاء الدالة قبل اكتمال العمليات غير المتزامنة.
التطوير المحلي يتم من خلال Firebase Emulator Suite، الذي يتضمن محاكي Cloud Functions. الأمر firebase emulators:start يشغل خادماً محلياً بالدوال يمكن الوصول إليه على http://localhost:5001. المحاكي يدعم إعادة التحميل السريع عند تغيير الكود ومعزول تماماً عن بيئة الإنتاج، مما يسمح بالاختبار دون مخاطرة بالبيانات الحقيقية.
التبعيات لدوال Cloud Functions تُدار عبر package.json. Firebase يثبت فقط تبعيات الإنتاج (dependencies، وليس devDependencies). حجم حزمة الدوال يؤثر على وقت البدء البارد: يُوصى بتقليل عدد التبعيات. تبعية firebase-admin مثبتة مسبقاً لـ Firebase Admin SDK — لا حاجة لإضافتها يدوياً.
البيانات السرية (مفاتيح API، الرموز) يجب ألا تُخزن في كود الدالة. استخدم functions.config() لتخزين التكوين: firebase functions:config:set stripe.key=“sk_...”. القيم مشفرة ومتاحة في وقت التشغيل عبر functions.config().stripe.key. للتكوينات التسلسلية الكبيرة، استخدم Google Cloud Secret Manager.
تسجيل السجلات في Cloud Functions يتم عبر console.log وconsole.warn وconsole.error. جميع السجلات تُجمع تلقائياً في Google Cloud Logging وتكون متاحة في وحدة تحكم Firebase (Functions > Logs). للتسجيل المنظم، استخدم مكتبات winston أو pino التي تدعم تنسيق JSON ومستويات التسجيل.
معالجة الأخطاء أمر بالغ الأهمية للموثوقية: استثناء غير معالج في Promise ينهي الدالة بخطأ، وبعدها Firebase يعيد المحاولة تلقائياً مع تأخير أسي. عدد مرات إعادة المحاولة قابل للتكوين: من 0 إلى لا نهاية. للمشغّلات المستندة إلى الأحداث، يُوصى بتمكين إعادة المحاولة لضمان معالجة كل حدث حتى أثناء الأعطال المؤقتة للخدمات الخارجية.
البدء البارد (cold start) هو التأخير في أول استدعاء لدالة بعد فترة خمول، عندما يتم تحميل وتهيئة الحاوية مع الكود من جديد. وفقاً لوثائق Firebase (2026)، يستغرق البدء البارد من 200 مللي ثانية إلى ثانيتين حسب حجم الحزمة وعدد التبعيات والمنطقة. لواجهة المستخدم، التأخير الذي يتجاوز ثانية واحدة ملحوظ وقد يؤثر على تجربة المستخدم.
طرق تقليل البدء البارد: تقليل التبعيات، استخدام TypeScript مع التجميع إلى CommonJS، تقليل حجم حزمة الدوال، تعيين حد أدنى لعدد الحاويات النشطة. Firebase Cloud Functions v2 (الجيل الثاني) يسمح بتعيين minInstances — الحد الأدنى لعدد الحاويات الدافئة الجاهزة دائماً لمعالجة الطلبات. الاحتفاظ بالحاويات دافئة يترتب عليه رسوم عن وقت الخمول.
التوسع في Cloud Functions يحدث تلقائياً: مع زيادة حجم الطلبات، Firebase ينشئ حاويات جديدة. افتراضياً، الحد الأقصى لعدد الحاويات المتوازية هو 3000 (حصة مشروع Google Cloud). كل حاوية تعالج طلباً واحداً في كل مرة. إذا كانت الدالة سريعة (أقل من 100 مللي ثانية)، يمكن لحاوية واحدة معالجة حتى 10 طلبات في الثانية، مما يوفر إنتاجية ذروة تصل إلى 30,000 طلب في الثانية لكل مشروع.
minInstances هو معامل يحجز عدداً محدداً من الحاويات ويبقيها دافئة. يُوصى به لدوال HTTPS الحرجة حيث زمن وصول البدء البارد غير مقبول. على سبيل المثال، لنقطة نهاية المصادقة، اضبط minInstances: 1. maxInstances يحد من العدد الأقصى للحاويات المتوازية، وهو مفيد لمنع النمو غير المنضبط للتكاليف أثناء الارتفاعات المفاجئة في حركة المرور.
التكوين يتم في الكود: functions.runWith({ minInstances: 1, maxInstances: 10 }). مهم: minInstances يزيد التكلفة لأن الحاويات تعمل باستمرار. لمشاريع الاختبار، يجب تعطيل minInstances. للإنتاج، يُوصى بـ minInstances لجميع دوال HTTPS العامة و0 للمشغّلات المستندة إلى الأحداث حيث تأخير ثانية واحدة غير حرج.
منطقة النشر تؤثر على زمن الوصول للمستخدمين النهائيين وتكلفة حركة المرور الصادرة. Firebase Cloud Functions متاحة في أكثر من 30 منطقة من Google Cloud. للتطبيقات المحمولة، اختر المنطقة الأقرب لجمهورك المستهدف: us-central1 للأمريكتين، europe-west1 لأوروبا، asia-east2 لآسيا. لا يمكن تغيير المنطقة بعد النشر دون إعادة نشر الدالة.
تغيير المنطقة يتم عبر معامل region في الكود: functions.region('europe-west1'). جميع الدوال في ملف واحد يمكن أن يكون لها مناطق مختلفة. للمشاريع العالمية، يُوصى بنشر الدوال في مناطق متعددة واستخدام Cloud Load Balancing لتوزيع حركة المرور، على الرغم من أنه لمعظم التطبيقات المحمولة، منطقة واحدة كافية إذا تم اختيارها بشكل صحيح.
دعنا نلقي نظرة على أمثلة عملية لدوال Cloud Functions بلغة TypeScript. الكود يستخدم Firebase Functions SDK v2 (الجيل الثاني) مع بناء جملة وحدات ES. الأمثلة تشمل معالجة حدث إنشاء مستخدم، إنشاء صورة مصغرة عند رفع صورة، ونقطة نهاية HTTPS بسيطة لواجهة REST API. جميع الدوال غير متزامنة وتعيد Promise للإنهاء الصحيح للحاوية.
قبل التشغيل، تأكد من تحديث Firebase CLI إلى الإصدار 13+: npm install -g firebase-tools. دوال v2 تتطلب خطة التسعير Blaze. التهيئة: firebase init functions مع اختيار TypeScript.
المثال الأول — إنشاء مستند في Firestore عند تسجيل مستخدم جديد. الدالة تُفعَّل بحدث auth.user().onCreate وتكتب ملفاً شخصياً أساسياً في مجموعة users/{uid}. هذا يضمن أن لكل مستخدم مسجل مستنداً بالحقول اللازمة.
import * as functions from "firebase-functions"
import * as admin from "firebase-admin"
admin.initializeApp()
export const createUserProfile = functions.auth
.user()
.onCreate(async (user) => {
const profile = {
email: user.email,
displayName: user.displayName ?? "User",
createdAt: admin.firestore.Timestamp.now(),
role: "free",
avatarUrl: null,
}
await admin.firestore()
.collection("users")
.doc(user.uid)
.set(profile)
console.log(`Profile created for ${user.uid}`)
})
الدالة createUserProfile غير متزامنة — تعيد Promise ينتظرها Firebase قبل الإنهاء. إذا فشلت الكتابة إلى Firestore (مثلاً بسبب صلاحيات غير كافية)، سيتم إعادة محاولة الدالة تلقائياً (إذا كانت إعادة المحاولة مفعلة). الحقل role بقيمة “free” يسمح بتنفيذ قيود الخطة المجانية مباشرة في Security Rules الخاصة بـ Firestore عبر مقارنة resource.data.role بمستوى الوصول المطلوب.
المثال الثاني — مشغّل Storage لإنشاء صورة مصغرة تلقائياً بعد رفع صورة. الدالة تنشئ نسخة مصغرة بحجم 200×200 بكسل وتحفظها في مسار الملف الأصلي بالبادئة thumb_. معالجة الصور تستخدم مكتبة sharp التي تدعم جميع التنسيقات الشائعة وتعمل في بيئة Node.js دون تبعيات نظام.
import * as path from "path"
import * as os from "os"
import * as sharp from "sharp"
export const generateThumbnail = functions.storage
.object()
.onFinalize(async (object) => {
if (!object.contentType?.startsWith("image/")) return
const filePath = object.name!
const thumbPath = filePath.replace(
/(\.\w+)$/, "_thumb$1"
)
const bucket = admin.storage().bucket()
const tempDir = os.tmpdir()
const tempFile = path.join(tempDir, path.basename(filePath))
await bucket.file(filePath).download({ destination: tempFile })
await sharp(tempFile)
.resize(200, 200, { fit: "cover" })
.toFile(tempFile.replace(/(\.\w+)$/, "_thumb$1"))
await bucket.upload(tempFile.replace(
/(\.\w+)$/, "_thumb$1"
), { destination: thumbPath })
})
الدالة generateThumbnail تتحقق من Content-Type للكائن وتتجاهل غير الصور، مما يوفر الموارد. لاستخدام sharp، يجب إضافة التبعية إلى package.json. الصورة المصغرة تُنشأ بمعامل fit: “cover”، الذي يقص الصورة من المنتصف إلى مربع 200×200 بكسل. بعد الإنشاء، تُرفع الصورة المصغرة مرة أخرى إلى نفس bucket باسم معدّل.
المثال الثالث — دالة HTTPS تنفذ نقطة نهاية REST API للتحقق من حالة الخادم. الدالة تقبل طلب GET وتعيد JSON بمعلومات حول حالة خدمات Firebase المتصلة بالمشروع. نقطة النهاية هذه مفيدة للمراقبة والأنظمة الخارجية التي تحتاج للتحقق من توفر الخلفية قبل إرسال البيانات.
import * as express from "express"
const app = express.Router()
app.get("/status", async (req, res) => {
try {
const db = admin.firestore()
await db.collection("_health").doc("check").get()
res.json({ status: "ok", timestamp: Date.now() })
} catch (error) {
res.status(503).json({ status: "error", message: error })
}
})
export const api = functions.https.onRequest(app)
الدالة api تستخدم express Router للتوجيه، وهو مناسب عند إنشاء نقاط نهاية متعددة في دالة واحدة. فحص الصحة يكتب في Firestore في مجموعة _health، مما يسمح بالتحقق المتزامن من توفر Firestore. للإنتاج، يُوصى بإضافة مصادقة الطلب عبر مفتاح API أو رمز Firebase Auth لمنع إساءة استخدام نقطة النهاية العامة.
Cloud Functions تُستخدم عادةً للمهام التي لا يمكن أو لا يُرغب في تنفيذها على العميل: إرسال إشعارات الدفع، إنشاء معاينات للصور المرفوعة، التكامل مع أنظمة الدفع الخارجية، مراقبة المحتوى، مزامنة البيانات بين Firebase وخدمات الطرف الثالث. النموذج بدون خادم يجعل هذه المهام اقتصادية: الدفع فقط مقابل وقت التنفيذ الفعلي للكود.
التكامل مع أنظمة الدفع هو سيناريو نموذجي للتطبيقات ذات المشتريات داخل التطبيق. Cloud Functions تستقبل webhook من مزود الدفع (Stripe، PayPal)، تتحقق من توقيع الطلب، تحدث حالة الاشتراك في Firestore، وترسل تأكيداً للمستخدم. كل الكود يُنفذ على الخادم دون خطر التلاعب بالبيانات على العميل. وفقاً لوثائق Stripe (2026)، معالجة webhook تستغرق أقل من 500 مللي ثانية.
المراقبة الذكية للمحتوى تستخدم مشغّل Storage من Cloud Function للتحقق التلقائي من الصور المرفوعة عبر Google Cloud Vision API. الدالة ترسل الصورة إلى Vision API للكشف عن المحتوى غير الآمن (العنف، المحتوى للبالغين) وإذا تجاوزت الحد، تحذف الملف وتُعلم المسؤول. هذا السيناريو بالغ الأهمية لتطبيقات UGC ذات معارض المستخدمين.
تجميع البيانات — Cloud Functions كبديل لعدادات Firebase Realtime Database. بدلاً من قراءة وكتابة عداد على العميل (مما يؤدي إلى حالات سباق)، استخدم مشغّل onWrite من Firestore للتحديثات الذرية للحقول المجمعة. على سبيل المثال، دالة تحسب عدد إعجابات المنشور في كل مرة يتم فيها إضافة أو حذف مستند في المجموعة الفرعية /posts/{postId}/likes/{userId} وتحدث حقل likesCount في المستند الأصلي.
الأسئلة الشائعة
الوقت الأقصى للتنفيذ يعتمد على النوع: دوال HTTPS — 9 دقائق، المشغّلات المستندة إلى الأحداث — 60 ثانية (v2: حتى 60 دقيقة). للعمليات الطويلة، استخدم Cloud Tasks أو Pub/Sub مع معالجة غير متزامنة. المهلة الزمنية تُضبط في الكود عبر runWith({ timeoutSeconds: 120 }).
استخدم Firebase Emulator Suite: firebase emulators:start --only functions. المحاكي يشغل الدوال محلياً على المنفذ 5001 مع دعم إعادة التحميل السريع. لمشغّلات Firestore وAuth، المحاكي يستبدل الخدمات الحقيقية، مما يسمح باختبار السيناريوهات دون مخاطرة بالبيانات الإنتاجية.
الجيل الثاني يستخدم Google Cloud Run وEventarc، مما يوفر مهلة زمنية أطول (حتى 60 دقيقة)، معالجة متزامنة للطلبات بواسطة حاوية واحدة، وتكاملاً محسّناً مع خدمات Google Cloud. الجيل الأول يستخدم Google Cloud Functions ومحدود بـ 60 ثانية للدوال المستندة إلى الأحداث. Firebase توصي ببدء مشاريع جديدة بالجيل الثاني.
Firebase Cloud Functions تدعم رسمياً فقط Node.js (JavaScript وTypeScript). لـ Python، استخدم Google Cloud Functions مباشرة مع Firebase Admin SDK لـ Python. Firebase Admin SDK Python يدعم جميع العمليات باستثناء بعض المشغّلات الخاصة بـ Firebase المتاحة فقط عبر Node.js.
لـ الوصول المصادق عليه، تحقق من رمز Firebase ID في رأس Authorization: admin.auth().verifyIdToken(token). لـ التكامل بين الخادم والخادم، استخدم Firebase Admin SDK مع حساب خدمة أو مفاتيح API. لنقاط النهاية العامة مع تحديد السرعة، استخدم تحديد السرعة عبر Cloud Armor أو middleware.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا