أرسل الإشعار إلى شخص، لا إلى جهاز
لدى مستخدمك هاتف وحاسوب وتبويب في المتصفح. توقّف عن تخزين رموز الأجهزة: اربط الأجهزة بمعرّف المستخدم في نظامك وأرسل مرة واحدة إلى iOS وأندرويد والويب وmacOS.
5 دقائق قراءة

لدى مستخدمك هاتف وحاسوب وتبويب في المتصفح. توقّف عن تخزين رموز الأجهزة: اربط الأجهزة بمعرّف المستخدم في نظامك وأرسل مرة واحدة إلى iOS وأندرويد والويب وmacOS.
5 دقائق قراءة


معظم المستخدمين لا يبلّغون عن الأعطال، بل يغادرون. أعدّ تتبّع الأعطال في تطبيق Flutter خلال دقائق: ما الذي يُلتقط، وكيف تضيف السياق، وكيف تتخلص من الضجيج.
5 دقائق قراءة

إصدار قديم يتعطل مع الـ API الجديدة، أو الخادم يحتاج ساعة صيانة. اضبط قواعد التحديث ونوافذ الصيانة من لوحة التحكم وستلتزم بها كل التطبيقات خلال دقائق.
يعرف خادمك المستخدمَ بالمعرّف u_8241. أما الإشعارات فتذهب إلى أجهزة: آيفون، وجهاز أندرويد لوحي، وتبويب في متصفح كروم على الحاسوب، وربما تطبيق الماك. والطريقة المعتادة للربط بينهما جدول device_tokens: تحفظ كل رمز عند تسجيله، وتحدّثه عند الخروج، وتحذفه حين يخبرك المزوّد أنه لم يعد صالحاً، وتمرّ على القائمة كلها مع كل إرسال.
ليركس يرفع عنك هذا الجدول. كل تطبيق يخبر ليركس بمن سجّل دخوله، وخادمك يرسل إلى معرّف المستخدم في نظامك. فيجد ليركس كل جهاز يستخدمه هذا الشخص على كل المنصات، ويُبلغك بحالة التسليم لكل جهاز.

كل منصة تحتاج بيانات اعتمادها في لوحة التحكم (الإشعارات ← الإعدادات) وبضعة أسطر في التطبيق:
| المنصة | في لوحة التحكم | في التطبيق |
|---|---|---|
| iOS وmacOS | ارفع مفتاح APNs بصيغة .p8 (مفتاح واحد للاثنين) |
خاصية Push Notifications، وBackground Modes ← Remote notifications |
| أندرويد | ارفع ملف حساب الخدمة (service account) من Firebase بصيغة JSON | لا شيء: لا ملف google-services.json ولا إضافة Google Services |
| الويب | Web Push ← Generate keys | انسخ ملف الـ service worker lerix-sw.js إلى موقعك |
على أندرويد تجلب الحزمة معرّف المرسل (sender id) الخاص بمشروعك من ليركس أثناء التشغيل، ولهذا لا يحمل التطبيق ملف إعدادات Firebase.
في Flutter، الإشعارات في حزمة مستقلة بجانب الحزمة الأساسية:
dependencies:
lerix_flutter: ^0.7.0
lerix_messaging: ^0.7.0
await Lerix.notifications.init();
await Lerix.notifications.requestPermissions();
وعلى الويب مع @lerix-dev/lerix-js:
import { Lerix } from '@lerix-dev/lerix-js';
Lerix.init({ apiKey: 'your-api-key', projectId: 'your-project-slug' });
await Lerix.notifications.init();
await Lerix.notifications.subscribe(); // asks for permission, registers the service worker
يدعم Safari إشعارات الويب بدءاً من macOS 13 وiOS 16.4، وعلى iOS للمواقع المضافة إلى الشاشة الرئيسية.
استدعِ setUser بمعرّف المستخدم في نظامك مباشرة بعد تسجيل الدخول، على كل منصة، وclearUser عند الخروج:
// Flutter
await Lerix.setUser(user.id);
// …
await Lerix.clearUser();
// Web
await Lerix.setUser(user.id);
// …
await Lerix.clearUser();
وللحزم الأصلية الزوج نفسه: Lerix.setUser(_:) على iOS وLerix.setUser(...) على أندرويد.
أمور تجعل استدعاءها آمناً في أي مكان:
clearUser() دائماً عند الخروج، وإلا فسيستمر الجهاز المشترك في تلقي إشعارات الشخص السابق.استخدم معرّفاً ثابتاً من نظامك. وتجنّب البريد ورقم الهاتف: فهما يتغيران، وهما بيانات شخصية لا حاجة لمشاركتها.
يتم الإرسال عبر الـ API العامة بـ مفتاح خاص للمشروع يملك صلاحية إرسال الإشعارات (إعدادات المشروع ← مفاتيح API):
curl -X POST https://api.lerix.dev/v1/your-project-slug/notifications/send \
-H "lerix-key: <your-private-key>" \
-H "Content-Type: application/json" \
-d '{
"title": "Your order shipped",
"body": "It arrives Thursday.",
"externalUserIds": ["u_8241", "u_77"],
"metadata": { "orderId": "A-1042" }
}'
ويخبرك الرد بما تحقق:
{
"success": true,
"notificationId": "b6b1a2b0-…",
"matchedUsers": 1,
"matchedDevices": 3,
"unknownUserIds": ["u_77"]
}
تضم unknownUserIds المعرّفات التي لا جهاز لها بعد، كشخص سجّل عبر الويب ولم يسمح بالإشعارات. وهذا ليس خطأً.
ومن خادم NestJS تفعل حزمة الخادم الشيء نفسه في استدعاء واحد:
const { matchedDevices, unknownUserIds } = await this.lerix.notifications.send({
title: 'New message',
body: 'You have a reply',
externalUserIds: [user.id],
});
ولحزمتي Python (lerix) و.NET (Lerix) الخيار نفسه (external_user_ids وExternalUserIds).
قواعد تستحق المعرفة:
externalUserIds أو deviceTokens أو موضوع (topic). ويُرفض الجمع بينها.imageUrl يضيف صورة: تلقائياً على أندرويد والويب، وعلى iOS يحتاج إلى Notification Service Extension.metadata تصل إلى التطبيق مع الإشعار، للروابط العميقة ونحوها.sentAt تجدول الإرسال. ويُبحث عن الأجهزة من جديد وقت الإرسال، فمن سجّل دخوله على هاتف جديد بعد الجدولة يصله الإشعار أيضاً.ويمكنك فعل ذلك من لوحة التحكم: إرسال إشعار ← المستخدمون، ألصق المعرّفات، فتعرض لك عدد الأجهزة التي سيصلها الإشعار قبل الإرسال.
setUser تعمل داخل التطبيق، فبدون تحقق يستطيع تطبيق معدّل أن يستدعي setUser('u_8241') ويبدأ بتلقي إشعارات ذلك الشخص. التحقق من الهوية يسدّ هذه الثغرة: خادمك يوقّع معرّف المستخدم، وليركس لا يقبل إلا المعرّفات ذات التوقيع الصحيح.
LERIX_IDENTITY_SECRET. يُعرض مرة واحدة فقط.import { createHmac } from 'node:crypto';
const lerixHash = createHmac('sha256', process.env.LERIX_IDENTITY_SECRET!)
.update(user.id, 'utf8')
.digest('hex');
وتوفّر حزمة NestJS ذلك عبر identityHash(secret, user.id)، وحزمة Python عبر identity_hash.
await Lerix.setUser(user.id, identityHash: session.lerixHash);
await Lerix.setUser(user.id, { identityHash: session.lerixHash });
setUser بلا توقيع صحيح.لا تضع السر داخل أي تطبيق أبداً. وزر Rotate secret يستبدله، فتتوقف التوقيعات المحسوبة بالسر القديم عن العمل.
كل إرسال يسجّل تسليماً لكل جهاز مع منصته (ios وandroid وweb وmacos وwindows) وحالته وسبب الفشل إن فشل:
curl https://api.lerix.dev/v1/your-project-slug/notifications/<notificationId>/deliveries \
-H "lerix-key: <your-private-key>"
وإذا لم تُعدّ منصة ما بعد (لم يُرفع مفتاح Apple مثلاً) تُسجَّل أجهزتها بالحالة PLATFORM_NOT_CONFIGURED، وتصل الإشعارات إلى بقية الأجهزة في الإرسال نفسه كالمعتاد. والرموز التي يبلّغ المزوّد أنها غير صالحة تُحذف تلقائياً.
أرسلت شيئاً بالخطأ؟ زر Unsend يزيله من أجهزة iOS وأندرويد وmacOS (التي تعمل بإصدار حزمة يدعم ذلك) ويبقيه في السجل بحالة "سُحب". أما إشعارات الويب وWindows فلا يمكن سحبها بعد ظهورها.
lerix_messaging في Flutter، والـ service worker على الويب).setUser(yourUserId) بعد الدخول وclearUser() عند الخروج، على كل منصة.externalUserIds بمفتاح خاص.ثم سجّل الدخول بالحساب نفسه على جهازين وأرسل إلى نفسك إشعاراً واحداً. رؤيته يصل إلى الاثنين هي الفكرة كلها.
6 دقائق قراءة

السطر index-8f3a1c.js:1:48213 لا يخبرك بشيء. ارفع خرائط المصدر من البناء ليشير كل خطأ إلى ملفك وسطرك ودالتك، وتعرّف على طريقة تجميع الأخطاء في مشكلات.
6 دقائق قراءة