انتقل إلى المحتوى الرئيسي
شرح تطبيقي

الإشعارات الفورية في Expo: دليل شامل تمنّيتُ وجوده عندما بدأتُ العمل

4 دقائق قراءة

إشعارات Expo في React Native: خطوات مجرّبة وأخطاء واقعية تعلّمتها أثناء إطلاق تطبيقات لعملاء في الإمارات.

react-nativeexpopush-notificationsmobile-devtutorial

في العام الماضي، وفي تمام الساعة 2:47 صباحًا في شقتي في أبو ظبي، كنت أحدّق في أيقونة الإشعارات على جهاز اختبار React Native الخاص بي والتي كانت ترفض عرض أي شيء. لقد أمضيت 14 ساعة متواصلة في محاولة جعل تطبيق مدير مشروع خاص بأحد عملاء البناء يرسل إشعارات فورية. وثائق Expo؟ مليئة بالثغرات. مقاطع الفيديو التعليمية؟ قديمة بثلاث إصدارات من SDK. كان العميل بحاجة إلى تنبيهات في الوقت الفعلي للمشرفين على المواقع باللغة العربية - وكان لدي 12 ساعة قبل اجتماعهم الصباحي في دبي.

إليك كل ما تمنيت لو كان لدي في تلك الليلة.

رقصة الإعداد (وما لا يخبرونك به)

يخفي Expo التعقيد وراء تجريدات لطيفة حتى لا يعود بإمكانه ذلك. بالنسبة للإشعارات، ستحتاج إلى:

  1. إعداد مشروعك باستخدام expo-notifications و expo-device
  2. تكوين مناسب في app.json (المزيد عن ذلك لاحقًا)
  3. جهاز Android مزود بخدمات Google Play - لن يعمل المحاكي

لقد أمضيت ست ساعات في إحدى المرات لاكتشاف أننا نسينا حقل package في app.json. ليس projectId أو slug - اسم حزمة Android الحرفي. الخطأ؟ لا يوجد أي مؤشر. استغرق الأمر مني البحث في سجلات native باستخدام adb لأكتشف أن طبقة JS لم تكن حتى تقوم بتحميل وحدة الإشعارات بسبب خطأ إملائي أساسي في ملف manifest.

بالنسبة لنظام iOS: أنت بحاجة إلى مفتاح مصادقة APNs + ملف تعريف تزويد. بدون أعذار. Android؟ بيانات اعتماد Firebase Cloud Messaging (FCM). لكن Expo يجرّد معظم هذا - حتى تنتقل إلى الإنتاج.

كتابة الكود الفعلي - لا تنسخ StackOverflow

التدفق الأساسي:

استيراد الوحدات:

javascript
import * as Notifications from "expo-notifications";
import { Platform } from "react-native";

طلب الأذونات:

javascript
Notifications.requestPermissionsAsync({
  ios: {
    allowAlert: true,
    allowBadge: true,
    allowSound: true,
  },
});

معالجة الإشعارات:

javascript
const subscription = Notifications.addNotificationReceivedListener((notification) => {
  // Your UI logic here
});

لكن انتظر - يموت معالج الإشعارات الخاص بك عند إغلاق التطبيق. لإيقاظه، تحتاج إلى شيئين:

  • •Notifications.setNotificationHandler
  • •إعداد خدمة الخلفية (في eas.json إذا كنت تستخدم التحديثات)

في إحدى المرات، قمت بالبرمجة لمدة 9 ساعات متواصلة معتقدًا أن addNotificationReceivedListener سيعمل على عمليات تشغيل الخلفية. تنبيه: لا يعمل. أنت بحاجة إلى مهام Headless JS لنظام Android و performFetchWithCompletionHandler على iOS.

خطأ SDK 54 الذي استمر 15 ساعة والذي حطمني

كان لدى هذا العميل تطبيق للعناية بالنباتات يمر عبر Expo SDK 54. كان كل شيء يعمل بشكل مثالي - حتى أضفنا Pushwoosh كموفر طرف ثالث. كانت رموز الإشعارات تستمر في إبطال نفسها.

اتضح أن وحدة Expo Notifications تتعارض مع Pushwoosh عندما يطلب كلاهما رموز FCM. الحل؟ تفرع حزمة expo-notifications. ليس الجواب الذي أردته، ولكنه الوحيد الذي نجح.

لا تفترض أبدًا أن مكتبات الطرف الثالث تعمل بشكل جيد. تحقق من AndroidManifest.xml بحثًا عن اشتباكات الأذونات:

xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE" />

ستحتاج أيضًا إلى هذه الأذونات إذا كنت تقوم بجدولة التنبيهات المحلية.

الاختبار سيئ لأن الأجهزة تكذب

المحاكي ≠ العالم الحقيقي.

في إحدى الليالي قبل إصدار Tawasul Limo، تم تشغيل الإشعارات المحلية بشكل جيد على أجهزة المحاكاة ولكنها فشلت بصمت على أجهزة Android الفعلية في جدة. السبب؟ متطلبات ForegroundService للإشعارات المنبثقة. لم يكن التطبيق مدرجًا في القائمة البيضاء في إعدادات البطارية على الأجهزة السعودية.

اختبر على الأجهزة الفعلية. ثم اختبر مرة أخرى على مصنع آخر. تتعامل Samsung مع وضع الخمول بشكل مختلف عن Xiaomi. لا توجد طريقة للالتفاف حول ذلك.

تعلم هذا الآن أيضًا: الإشعارات الصامتة (content-available: 1 في APNs) لا تعمل بشكل موثوق مع إصدارات Expo المُدارة. ستحتاج إلى الإخراج أو استخدام عملاء تطوير مخصصين.

جعله يعمل لعملاء الإمارات العربية المتحدة (لأن المناطق الزمنية مهمة)

في الساعة 4 صباحًا أثناء تصحيح الأخطاء مع فريق التسويق الخاص بأحد العملاء في الرياض، أدركت أننا قمنا بتشفير المناطق الزمنية للإشعارات إلى UTC+4. خلال شهر رمضان، خرجت تذكيراتهم الفورية متأخرة 5 ساعات. ليس مظهرًا رائعًا عندما تراسل بشأن خصومات الإفطار.

بالنسبة للتطبيقات الإقليمية:

  • •قم بتخزين المنطقة الزمنية للمستخدم في الواجهة الخلفية الخاصة بك
  • •استخدم moment-timezone في وظائف Node.js lambda
  • •قم دائمًا بتحويل الطوابع الزمنية للخادم إلى التوقيت المحلي للمستخدم قبل الإرسال

أحد مشاريعي، Greeny Corner، يقدم تذكيرات بالعناية بالنباتات باللغة العربية. اضطررت إلى إصلاح الحقل titleLocKey للترجمات - لا يتعامل FCM مع استبدال الأحرف غير اللاتينية خارج الصندوق. اضطررت إلى تقديم الرسالة الفعلية مسبقًا على الواجهة الخلفية.

ما وراء الأساسيات: الجدولة والروابط العميقة

تتوقف معظم الدروس التعليمية عند "انظر، هذا يعمل". يريد المستخدمون الحقيقيون:

  • •جدولة الإشعارات المتكررة (تذكيرات يومية بسقي النباتات لـ Greeny Corner)
  • •الربط العميق من الإشعارات (افتح معرف حجز معين في تطبيق Tawasul Limo)
  • •جلب البيانات في الخلفية (قم بتحديث قوائم العقارات في Reach Home)

للجدولة، استخدم:

javascript
Notifications.scheduleNotificationAsync({
  content: {
    title: "Water your plant 😊",
    body: "Don't forget!",
    data: { plantId: 123 },
  },
  trigger: {
    hour: 9,
    minute: 0,
    repeats: true,
  },
});

الربط العميق: تأكد من أن إعداد Linking الخاص بك يدعم نظام URI المخصص في حمولات بيانات الإشعارات. يتطلب iOS تكوينًا إضافيًا في Info.plist.

أفكار ختامية... والجزء الذي لا تشعر فيه بالذعر

أصعب جزء في شحن الإشعارات الفورية ليس كتابة الكود - بل هو تصحيح الأخطاء في الساعة 3 صباحًا عندما يتوقع أصحاب المصلحة عمليات تسليم معجزة. ستنسى بعض الأذونات في إصدار Android واحد. ستظهر وحدة تحكم Firebase الرموز على أنها نشطة في حين أنها ليست كذلك بوضوح.

عندما يحدث ذلك، تنفس. تحقق جيدًا من انتهاء صلاحية مفتاح مصادقة .p8 لنظام iOS. تأكد من أن EXPO_ANDROID_KEY في بيئتك يطابق حقًا المفتاح الموجود في وحدة تحكم Firebase Cloud Messaging.

لقد نسيت ذات مرة تمكين Google Cloud Messaging API في مشروع Firebase جديد. استغرق الأمر 8 ساعات من الصراخ في أجهزة Samsung حتى لاحظت HTTP 403 في السجلات.

الآن، اذهب واجعل إشعاراتك تعمل. ثم تعال اشتكِ من Firebase في الرسائل الخاصة.

يمكنك التواصل معي على sarahprofile.com/contact إذا واجهت حائطًا لا ينبغي لأحد أن يتسلقه بمفرده.

S

سارة

مطوّرة Full-Stack أولى ومعتمدة PMP — أبوظبي، الإمارات

أكثر من 7 سنوات في بناء تطبيقات ويب لشركات الإمارات والخليج. متخصصة في Laravel وNext.js وتطوير مواقع RTL العربية.

تعاون مع سارة