الحلقة 4: الإشعارات المحلية والجدولة الدقيقة
بعد أن قمنا بتثبيت الأساسيات من صلاحيات وقنوات، حان الوقت لتشغيل أول إشعارات حقيقية لنا. في هذا الدرس، ننتقل من النظرية إلى التطبيق العملي من خلال تعلم كيفية إرسال تنبيهات فورية وجدولة الرسائل المستقبلية بدقة متناهية.
سنغطي في هذا الدرس:
- تشريح الإشعار: فهم كائنات المحتوى (
content) والمحفز (trigger). - التنبيهات الفورية: إطلاق الإشعارات للحصول على رد فعل فوري للمستخدم.
- المحفزات الزمنية: تأخير التنبيهات بمدد زمنية محددة.
- المحفزات التقويمية: جدولة تذكيرات متكررة أو في تواريخ محددة.
- إدارة المعرفات: تتبع وإدارة المهام المجدولة الخاصة بك.
تشريح إشعار إكسبو
لإرسال إشعار، نستخدم الدالة scheduleNotificationAsync. تتطلب هذه الدالة كائناً واحداً للتكوين يحتوي على مفتاحين أساسيين:
content: يحدد ماذا يرى المستخدم (العنوان، النص، البيانات، الصوت).trigger: يحدد متى يراه المستخدم (الآن، بعد 5 دقائق، أو كل يوم اثنين).
تخيل الـ content كأنه الرسالة الموجودة داخل الظرف، والـ trigger كأنه تعليمات التسليم المكتوبة في الخارج.
1. التنبيهات الفورية (محفز "الآن")
أبسط أشكال الإشعارات هو الذي ينطلق على الفور. غالباً ما يستخدم هذا لرسائل الترحيب أو ردود الفعل الفورية للنظام.
index.tstypescriptimport * as Notifications from 'expo-notifications'; const fireInstantNotification = async () => { await Notifications.scheduleNotificationAsync({ content: { title: "مرحباً بك في NotifyMe! 👋", body: "لقد بدأت رحلة تنظيم مهامك الاحترافية الآن.", data: { type: "welcome" }, channelId: "tasks", // الربط بالقناة التي أنشأناها }, trigger: null, // 'null' تعني إطلاق الإشعار فوراً }); };
2. تأخير الإشعارات (الفترات الزمنية)
إذا كنت بحاجة إلى تذكير المستخدم بمهمة في المستقبل القريب (مثل: "ذكرني بعد 10 دقائق")، فإن TimeIntervalTrigger هي أداتك المناسبة.
index.tstypescriptconst remindInFiveMinutes = async () => { await Notifications.scheduleNotificationAsync({ content: { title: "تذكير بمهمة 📝", body: "حان وقت مراجعة أهدافك اليومية.", channelId: "tasks", }, trigger: { seconds: 5 * 60, // 5 دقائق بالثواني repeats: false, }, }); };
3. الجدولة بدقة عالية (المحفزات التقويمية)
بالنسبة لتطبيقات المهام أو أنظمة الجدولة، غالباً ما تحتاج إلى تنبيهات في أوقات محددة. يسمح CalendarTrigger بجداول معقدة ومتكررة بناءً على الوقت المحلي للمستخدم.
تذكير أسبوعي متكرر
index.tstypescriptconst scheduleMondaySync = async () => { await Notifications.scheduleNotificationAsync({ content: { title: "مزامنة أسبوعية 🚀", body: "حدد أهدافك للأسبوع القادم.", channelId: "default", }, trigger: { weekday: 2, // الاثنين (الأحد = 1، الاثنين = 2، ...) hour: 9, minute: 0, repeats: true, }, }); };
4. إدارة المعرفات والبيانات الوصفية "المخفية"
في كل مرة تقوم فيها بجدولة إشعار، يعيد إكسبو معرفاً فريداً (identifier). هذه السلسلة النصية هي الطريقة الوحيدة لإلغاء أو تحديث هذا الإشعار المحدد لاحقاً.
index.tstypescriptconst notificationId = await Notifications.scheduleNotificationAsync({ content: { title: "تنبيه مجدول" }, trigger: { seconds: 60 } }); console.log("المعرف المسجل:", notificationId);
خاصية data
يعد حقل data في كائن المحتوى أحد أقوى الميزات. لا يرى المستخدم هذا الكائن أبداً، ولكن يمكن لتطبيقك قراءته عندما يتم النقر على الإشعار. هذه هي الطريقة التي تنفذ بها "الروابط العميقة" (Deep Linking) — على سبيل المثال، إرسال المستخدم مباشرة إلى مشروع معين أو غرفة دردشة.
التطبيق العملي
في ملف HomeScreen.tsx الخاص بك، يمكنك الآن ربط هذه الدوال بعناصر واجهة المستخدم لرؤية النتائج في الوقت الفعلي.
App.jstsx<Button title="اختبار فوري" onPress={fireInstantNotification} /> <Button title="ذكرني بعد دقيقة" onPress={() => scheduleTimedNotification(60)} />
“[!TIP] عند اختبار الإشعارات المجدولة، تأكد من وضع تطبيقك في الخلفية (بالضغط على زر الصفحة الرئيسية). بشكل افتراضي، قد تتصرف الإشعارات بشكل مختلف أو يتم حجبها إذا كان التطبيق مفتوحاً حالياً في المقدمة.
التحدي الخاص بك
قم ببرمجة تذكير "تفكير يومي" (Daily Reflection) ينطلق كل مساء في الساعة 8:00 مساءً. قم بتمرير قطعة فريدة من البيانات (data) (مثل: { screen: 'Reflection' }) والتي سنستخدمها في الدرس القادم لتوجيه المستخدم داخل التطبيق.