حول المحتوى:
دليل عملي لبناء نظام Push Notifications وربطه مع Firebase باستخدام RabbitMQ كوسيط.
في هذا الدليل العملي سنتعلّم خطوة بخطوة كيفية تصميم نظام Push Notifications للتطبيقات (موبايل أو ويب) بالاعتماد على RabbitMQ كوسيط للرسائل، وربطه مع Firebase Cloud Messaging (FCM) لإرسال الإشعارات الفعلية إلى أجهزة المستخدمين.
هذا المقال مكمّل لمجموعة شروحات افهم صح حول تصميم أنظمة الإشعارات وقابلية التوسع باستخدام Message Queues. يمكنك الرجوع أيضاً إلى:
الهدف هو بناء نظام مرن، قابل للتوسع، وسهل الصيانة، يفصل منطق إنشاء الإشعارات عن منطق إرسالها الفعلي عن طريق Firebase، باستخدام بنية قائمة على الرسائل (Message-based Architecture).
خدمة Firebase Cloud Messaging توفّر واجهة API لإرسال الإشعارات إلى الأجهزة، لكن الاعتماد مباشرةً عليها من داخل الكود التطبيق الأساسي (Monolith أو Microservices) يخلق عدّة مشاكل:
هنا يأتي دور RabbitMQ كوسيط رسائل:
بهذا يكون لدينا خط أنابيب (Pipeline) واضح: التطبيق / الخدمة → RabbitMQ → Notification Service → Firebase → جهاز المستخدم.
قبل الدخول في التفاصيل التقنية، لنرسم المعمارية العامة للنظام الذي نريد بناءه:
بهذا التصميم نستفيد من نمط Event-Driven / Message-Driven Architecture، ونفصل مسؤوليات النظام بشكل واضح.
لبدء استخدام Firebase Cloud Messaging، نحتاج:
يمكن تشغيل RabbitMQ محلياً أو على خادم إنتاجي (Production Server):
notifications.exchange (نوعه غالباً direct أو topic).notifications.push.firebase.notifications.push.firebase.هذه الخدمة هي المسؤولة عن:
notifications.push.firebase.يمكن بناء هذه الخدمة بأي لغة مفضلة لديك (Python، Node.js، Go، إلخ). إذا كنت تستخدم Python فيمكنك الاستفادة من الأدوات التي شرحناها في دمج RabbitMQ مع FastAPI: بناء نظام إشعارات عالي الأداء.
أحد أهم عناصر نجاح نظام rabbitmq push notifications firebase هو تصميم Payload الرسالة التي سيتم وضعها في الـ Queue. يجب أن تكون:
مثال لرسالة JSON يمكن وضعها في Queue:
{
"notification_id": "123456",
"user_id": 789,
"device_tokens": [
"fcm_token_1",
"fcm_token_2"
],
"title": "طلب جديد",
"body": "تم استلام طلبك بنجاح",
"data": {
"order_id": 555,
"type": "order_created"
},
"priority": "high",
"created_at": "2024-04-01T10:30:00Z",
"retries": 0
}
المهم أن تحتوي الرسالة على:
مثلاً في Backend API (باستخدام FastAPI أو Django أو أي إطار آخر) يكون لدينا Endpoint مثل:
POST /api/notifications/send
يستقبل بيانات مثل:
{
"user_id": 789,
"title": "طلب جديد",
"body": "تم استلام طلبك بنجاح",
"data": {
"order_id": 555,
"type": "order_created"
}
}
بدلاً من أن يتصل الـ Backend مباشرةً مع FCM، يقوم بـ:
بناءً على إعدادات الـ Exchange وBinding، يتم توجيه الرسالة نحو:
Queue: notifications.push.firebase
من الآن فصاعداً، الـ Backend أنهى مهمته سريعاً، وعاد يستجيب للعميل (Client) دون انتظار تنفيذ الإرسال الفعلي للإشعار.
الـ Worker يعمل بشكل مستمر:
retries وإعادة النشر أو ترك الرسالة ليتم إعادة استهلاكها.من أجل دمج rabbitmq push notifications firebase بشكل فعّال، ستحتاج إلى معرفة شكل طلب FCM. لنأخذ مثالاً مبسطاً باستخدام HTTP v1 API (المُفضَّل حالياً):
POST https://fcm.googleapis.com/v1/projects/YOUR_PROJECT_ID/messages:send
Authorization: Bearer <ACCESS_TOKEN>
Content-Type: application/json
{
"message": {
"token": "fcm_token_1",
"notification": {
"title": "طلب جديد",
"body": "تم استلام طلبك بنجاح"
},
"data": {
"order_id": "555",
"type": "order_created"
},
"android": {
"priority": "HIGH"
},
"apns": {
"headers": {
"apns-priority": "10"
}
}
}
}
في حال أردت إرسال إشعار لأكثر من Token، يمكنك إما:
في الواقع العملي، الاتصال مع Firebase قد يفشل لعدة أسباب:
من المهم تصميم منطق Retry جيد. يمكن الاستفادة هنا من مفاهيم Dead Letter Queue التي شرحناها في مقال كيفية التعامل مع الرسائل الفاشلة في Kafka وRabbitMQ باستخدام Dead Letter Queue.
استراتيجية عملية:
retries (محاولات سابقة).notifications.push.firebase.dlq.يمكنك تقسيم الإشعارات حسب النوع أو الأهمية:
notifications.push.firebase.high لإشعارات الحرجة (مثل معاملات مالية).notifications.push.firebase.normal للإشعارات العادية (مثل تحديثات عامة).هذا يسمح لك بتخصيص عدد أكبر من الـ Consumers للإشعارات عالية الأهمية، والتحكم في أولويات المعالجة.
بدلاً من إرسال نصوص جاهزة من الـ Backend في كل مرة، يمكنك:
من المهم جداً توثيق:
هذا يساعدك على:
عند إرسال حمل ضخم من الإشعارات (مثلاً Broadcast لجميع المستخدمين)، يجب:
للتوضيح فقط (المثال ليس كود إنتاجي كامل، لكنه يوضّح الفكرة العامة):
import json
import pika
def publish_notification(message: dict):
connection = pika.BlockingConnection(
pika.ConnectionParameters(host='localhost')
)
channel = connection.channel()
exchange = 'notifications.exchange'
routing_key = 'notifications.push.firebase'
channel.exchange_declare(exchange=exchange, exchange_type='direct', durable=True)
channel.queue_declare(queue='notifications.push.firebase', durable=True)
channel.queue_bind(queue='notifications.push.firebase', exchange=exchange, routing_key=routing_key)
channel.basic_publish(
exchange=exchange,
routing_key=routing_key,
body=json.dumps(message),
properties=pika.BasicProperties(
delivery_mode=2 # make message persistent
)
)
connection.close()
import json
import pika
import requests
FCM_ENDPOINT = "https://fcm.googleapis.com/fcm/send"
FCM_SERVER_KEY = "YOUR_FCM_SERVER_KEY"
def send_to_fcm(payload):
headers = {
"Authorization": f"key={FCM_SERVER_KEY}",
"Content-Type": "application/json"
}
response = requests.post(FCM_ENDPOINT, headers=headers, json=payload, timeout=5)
response.raise_for_status()
return response.json()
def callback(ch, method, properties, body):
message = json.loads(body)
try:
for token in message["device_tokens"]:
fcm_payload = {
"to": token,
"notification": {
"title": message["title"],
"body": message["body"]
},
"data": message.get("data", {})
}
send_to_fcm(fcm_payload)
ch.basic_ack(delivery_tag=method.delivery_tag)
except Exception as e:
# في نظام حقيقي يجب هنا تطبيق منطق Retry / DLQ
print("Error:", e)
ch.basic_nack(delivery_tag=method.delivery_tag, requeue=True)
def start_worker():
connection = pika.BlockingConnection(
pika.ConnectionParameters(host='localhost')
)
channel = connection.channel()
channel.basic_qos(prefetch_count=10)
channel.basic_consume(queue='notifications.push.firebase', on_message_callback=callback)
channel.start_consuming()
هذا النموذج يربط بشكل مباشر بين RabbitMQ وFirebase عبر Worker، ويبيّن بشكل عملي كيف يعمل نظام rabbitmq push notifications firebase.
استخدام RabbitMQ كوسيط رسائل مع Firebase Cloud Messaging يمنحك نظام Push Notifications:
إذا كنت ترغب في تعميق الفهم حول تصميم أنظمة إشعارات قوية باستخدام RabbitMQ في بيئة Microservices، راجع أيضاً:
بهذا تكون قد حصلت على صورة واضحة وعملية لكيفية بناء نظام Push Notifications متكامل، يبدأ من تطبيق المستخدم، يمر عبر RabbitMQ، وينتهي عند Firebase لإيصال الإشعارات إلى الأجهزة بكفاءة وموثوقية عالية.
دليل عملي لبناء نظام Push Notifications وربطه مع Firebase باستخدام RabbitMQ كوسيط.
مساحة اعلانية