تتبع زوار الموقع الإلكتروني مباشرة دون الحاجة إلى اشتراكات
أراد أحد العملاء معرفة من يتواجد على موقعه الإلكتروني في الوقت الفعلي.
لقد أعجبهم ويدجت Tidio ولكنهم لم يرغبوا في دفع رسوم اشتراك.
تمثل التحدي في جزأين:
- الموقع يستخدم WordPress على استضافة مختلفة.
- لم أتمكن من إضافة Firebase مباشرة إلى إعدادات WordPress.
قمت ببناء أداة تتبع خارجية باستخدام Firebase. إليكم طريقة عملها.
الحل
استخدمت وسم script واحد في ترويسة (header) WordPress. يتصل هذا السكربت بمشروع Firebase مستقل.
• التواجد المباشر (Live Presence): استخدمت Firebase Realtime Database مع دالة onDisconnect(). تقوم هذه الدالة تلقائيًا بإزالة المستخدم من قائمة "المتصلين" عند إغلاق علامة التبويب أو فقدان الاتصال.
• سجل الزوار (Visitor History): استخدمت Netlify Function لكتابة البيانات في Firestore. يتيح ذلك تحديد الموقع الجغرافي عبر عنوان IP من جانب الخادم (server-side).
• الأمان (Security): استخدمت المصادقة المجهولة (anonymous authentication). يمكن للزوار الكتابة فقط في عقدة الجلسة (session node) الخاصة بهم، بينما يمكن للمسؤول فقط قراءة القائمة الكاملة.
الأخطاء البرمجية المحيرة
لم تكن عملية البناء سلسة، حيث واجهت ثلاث عقبات تقنية رئيسية.
1. فخ التخزين المؤقت (The Caching Trap)
أظهر السجل صفر جلسات. اكتشفت أن سكربت التتبع كان لديه سياسة تخزين مؤقت (cache policy) لمدة عام كامل، مما جعل الزوار عالقين في استخدام نسخة قديمة من السكربت.
- الحل: قمت بتعيين سياسة تخزين مؤقت لمدة خمس دقائق لسكربت التتبع.
2. خطأ CORS الوهمي (The Fake CORS Error)
أبلغ المتصفح عن خطأ CORS. اعتقدت أن المشكلة تتعلق بالقائمة البيضاء للنطاقات (domain whitelist). لكن اختبار curl بسيط أظهر أن الخادم يعمل بشكل جيد.
الحقيقة كانت مختلفة؛ كان الخادم ينهار (crashing) في الواقع.
في Node.js، إذا استخدمت رمز الحالة 204، فلا يمكنك استخدام سلسلة نصية فارغة كجسم للرد (body)، بل يجب استخدام null. تسببت السلسلة النصية الفارغة في حدوث انهيار قبل إرسال ترويسات CORS. وبما أن المتصفح لم يجد أي ترويسات، فقد افترض أنها مشكلة CORS.
- الحل: تغيير جسم الرد من
''إلىnull.
3. فجوة البيانات المفقودة (The Missing Data Gap)
لم تُرجع الفلاتر الخاصة بـ "اليوم" أو "آخر 7 أيام" أي نتائج، كما ظهرت مواقع بعض المستخدمين كـ "غير معروف" (Unknown). حدث هذا لأنني كنت أحسب الطابع الزمني (timestamp) والموقع فقط عند أول تحميل للصفحة. إذا كان لدى المستخدم جلسة قديمة في متصفحه، فإن الخادم سيفقد حدث "البداية" (start event).
- الحل: جعلت العملية idempotent (أي لا تتغير النتيجة بتكرار العملية). الآن يقوم السكربت بإعادة حساب هذه القيم مع كل حدث.
الدروس المستفادة الرئيسية
• خطأ CORS في المتصفح ليس دائمًا مشكلة في الإعدادات؛ فقد يخفي وراءه انهيارًا في الخادم. تحقق دائمًا من سجلات الخادم (server logs).
• اختبار curl POST لا يختبر المتصفح بشكل كامل، حيث ترسل المتصفحات طلب OPTIONS مسبقًا (preflight request). يجب أن يتضمن اختبارك هذا الطلب ليكون صحيحًا.
• استخدم null لحالات HTTP التي تعني "لا يوجد محتوى" مثل 204، ولا تستخدم السلاسل النصية الفارغة.
