Mustafa Frag نشر 29 ديسمبر 2025 أرسل تقرير نشر 29 ديسمبر 2025 السلام عليكم لدي تطبيق خدمي يعرض خدمات المدينة وأريد أن أضيف فيه غرف دردشة لكل قرية شات بسيط لكي يسأل الناس عن الخدمات المختلفة في المدينة ، ومعي قاعدة بيانات علي موقع firebase 1 اقتباس
0 Mustafa Suleiman نشر 29 ديسمبر 2025 أرسل تقرير نشر 29 ديسمبر 2025 ستحتاج إلى كود HTML و CSS و JavaScript وليس جافاسكريبت فقط، ففي Firebase، سيتم تخزين البيانات بالشكل التالي تلقائيًا عند تشغيل الكود: { "chats": { "village_1": { "message_id_1": { "name": "أحمد", "text": "صباح الخير", "time": 123456 }, "message_id_2": { "name": "محمد", "text": "صباح النور", "time": 123458 } }, "village_2": { } } } أولاً عليك إنشاء ملف جديد باسم index.html وبه الكود التالي، ويجب استبدال جزء firebaseConfig ببيانات مشروعك الخاص من لوحة تحكم Firebase: <!DOCTYPE html> <html lang="ar" dir="rtl"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>دردشة خدمات المدينة</title> <style> body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #f4f4f9; margin: 0; padding: 20px; } .container { max-width: 600px; margin: 0 auto; background: white; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); overflow: hidden; } /* رأس الصفحة واختيار القرية */ .header { background: #007bff; padding: 15px; color: white; text-align: center; } select { padding: 10px; width: 80%; margin-top: 10px; border-radius: 5px; border: none; } /* منطقة الرسائل */ #messages-container { height: 400px; overflow-y: scroll; padding: 20px; border-bottom: 1px solid #ddd; display: flex; flex-direction: column; gap: 10px; } .message { background: #e9ecef; padding: 10px; border-radius: 10px; width: fit-content; max-width: 80%; } .message strong { display: block; font-size: 0.8em; color: #555; margin-bottom: 3px; } .message .text { font-size: 1em; } .message .time { font-size: 0.7em; color: #888; text-align: left; margin-top: 5px; display: block; } /* صندوق الإدخال */ .input-area { padding: 15px; display: flex; gap: 10px; background: #fff; } input[type="text"] { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 5px; } input#username { width: 20%; } button { padding: 10px 20px; background: #28a745; color: white; border: none; border-radius: 5px; cursor: pointer; } button:hover { background: #218838; } </style> </head> <body> <div class="container"> <div class="header"> <h2>مجتمع خدمات المدينة</h2> <select id="villageSelect"> <option value="village_center">اختر المنطقة / القرية</option> <option value="village_north">قرية الشمال</option> <option value="village_south">قرية الجنوب</option> <option value="village_east">حي الشرق</option> <option value="village_west">حي الغرب</option> </select> </div> <div id="messages-container"> <p style="text-align:center; color:#888;">اختر القرية لبدء المحادثة...</p> </div> <div class="input-area"> <input type="text" id="username" placeholder="اسمك" required> <input type="text" id="messageInput" placeholder="اكتب سؤالك هنا..." disabled> <button id="sendBtn" disabled>إرسال</button> </div> </div> <script type="module"> import { initializeApp } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-app.js"; import { getDatabase, ref, push, onChildAdded, query, limitToLast, off } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-database.js"; // إعدادات مشروعك (انسخها من Firebase Console) const firebaseConfig = { apiKey: "AIzaSyDxxxxxxxxx-xxxxxxxxxx", authDomain: "your-app.firebaseapp.com", databaseURL: "https://default-rtdb.firebaseio.com", // تأكد أن الرابط صحيح projectId: "your-app-id", storageBucket: "your-app.appspot.com", messagingSenderId: "123456789", appId: "1:123456789:web:xxxxxx" }; const app = initializeApp(firebaseConfig); const db = getDatabase(app); const villageSelect = document.getElementById('villageSelect'); const messagesContainer = document.getElementById('messages-container'); const messageInput = document.getElementById('messageInput'); const usernameInput = document.getElementById('username'); const sendBtn = document.getElementById('sendBtn'); let currentVillageRef = null; villageSelect.addEventListener('change', (e) => { const villageId = e.target.value; if (villageId === "village_center") { messageInput.disabled = true; sendBtn.disabled = true; return; } messageInput.disabled = false; sendBtn.disabled = false; messagesContainer.innerHTML = ''; if (currentVillageRef) { off(currentVillageRef); } loadMessages(villageId); }); function loadMessages(villageId) { const chatPath = `chats/${villageId}`; currentVillageRef = query(ref(db, chatPath), limitToLast(50)); // جلب آخر 50 رسالة فقط onChildAdded(currentVillageRef, (snapshot) => { const data = snapshot.val(); displayMessage(data.name, data.text, data.timestamp); }); } function displayMessage(name, text, timestamp) { const date = new Date(timestamp); const timeString = date.getHours() + ':' + String(date.getMinutes()).padStart(2, '0'); const msgDiv = document.createElement('div'); msgDiv.className = 'message'; msgDiv.innerHTML = ` <strong>${name}</strong> <span class="text">${text}</span> <span class="time">${timeString}</span> `; messagesContainer.appendChild(msgDiv); messagesContainer.scrollTop = messagesContainer.scrollHeight; } sendBtn.addEventListener('click', sendMessage); messageInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') sendMessage(); }); function sendMessage() { const text = messageInput.value; const name = usernameInput.value || "مجهول"; const villageId = villageSelect.value; if (text.trim() === "") return; push(ref(db, `chats/${villageId}`), { name: name, text: text, timestamp: Date.now() }); messageInput.value = ''; } </script> </body> </html> وللتوضيح دالة onChildAdded لا تجلب البيانات مرة واحدة فقط، بل تبقى تستمع لأي رسالة جديدة تُضاف في قاعدة البيانات وتعرضها فورًا دون الحاجة لتحديث الصفحة. و off() ضرورية عند التبديل بين القرى لإيقاف استقبال رسائل القرية السابقة، بينما push() تقوم بإنشاء مفتاح فريد ID لكل رسالة جديدة تلقائيًا وحفظها. ثم إنشاء قاعدة البيانات بالتوجه إلى Firebase Console ثم Build ثم Realtime Database واضغط Create Database. ولغرض التجربة فقط أثناء التطوير، اجعل القواعد عامة Public، ثم توجه لتبويب Rules في Realtime Database واستبدلها بـ: { "rules": { ".read": true, ".write": true } } ولكن انتبه عند نشر التطبيق للمستخدمين يجب تغيير القواعد لتسمح فقط للمستخدمين المسجلين بالكتابة. وفي كود HTML السابق ابحث عن const firebaseConfig واستبدل القيم الموجودة بالقيم التي تحصل عليها من إعدادات مشروعك من خلال التوجه للتالي Project Settings - ثم General ثم Your apps ثم SDK setup and configuration اقتباس
0 Sherif Aboghazala نشر 29 ديسمبر 2025 أرسل تقرير نشر 29 ديسمبر 2025 وعليكم السلام ورحمة الله وبركاته فكرة التطبيق ممتازة ومناسبة جدًا لطبيعة الخدمات المحلية، ووجود غرف دردشة لكل قرية سيزيد التفاعل ويجعل التطبيق حيًّا فعليًا. بما أنك تستخدم Firebase فاختيارك موفق، لأنه مناسب جدًا لهذا النوع من التطبيقات. سأشرح لك الفكرة بشكل متكامل من ناحية التصميم، قاعدة البيانات، وآلية العمل، دون الدخول في تعقيد غير ضروري. أولًا: الفكرة العامة للنظام أنت لا تحتاج إلى “غرفة دردشة” بالمعنى المعقد، بل نظام رسائل بسيط مرتبط بكل قرية. كل قرية يكون لها Chat خاص بها، وأي مستخدم يدخل القرية يستطيع القراءة والكتابة ضمن هذا الشات حسب الصلاحيات. ثانيًا: أي خدمة من Firebase تختار؟ Firebase يوفر حلّين مناسبين: Cloud Firestore و Realtime Database للتطبيقات التي تعتمد على الدردشة، Realtime Database أبسط وأسرع في التنفيذ، بينما Firestore أنظم وأفضل للتوسع مستقبلاً. إن كنت في البداية، أنصحك بـ Firestore لأنه أكثر مرونة وأسهل في التحكم بالصلاحيات. ثالثًا: تصميم قاعدة البيانات (Firestore) فكرة التصميم تكون هكذا منطقيًا: collection اسمها villages داخلها documents تمثل القرى كل document يحتوي معلومات القرية (الاسم، المعرف، إلخ) داخل كل قرية، collection اسمها chatMessages كل رسالة تكون document مستقل محتوى الرسالة عادة يكون: معرّف المستخدم اسم المستخدم نص الرسالة تاريخ الإرسال (Timestamp) اختياري: نوع الرسالة (نص، صورة لاحقًا) بهذا الشكل، كل قرية لها سجل دردشة منفصل وواضح. رابعًا: ربط المستخدمين بالدردشة أي مستخدم مسجّل دخول (باستخدام Firebase Authentication) يستطيع: الدخول إلى صفحة القرية تحميل آخر الرسائل إرسال رسالة جديدة من المهم أن تعتمد دائمًا على userId القادم من Firebase Auth، ولا تسمح للمستخدم بتمرير اسمه أو هويته يدويًا حتى لا يتم التلاعب. خامسًا: عرض الرسائل في الواجهة تستخدم Listener من Firestore للاستماع للتغييرات اللحظية. عند إضافة رسالة جديدة: تظهر فورًا لكل المستخدمين داخل نفس القرية دون تحديث الصفحة. تقوم بترتيب الرسائل حسب التاريخ من الأقدم إلى الأحدث، أو العكس حسب التصميم الذي تريده. سادسًا: الحماية ومنع الفوضى هذه نقطة مهمة جدًا. يجب ضبط Firebase Security Rules بحيث: لا يسمح بالقراءة والكتابة إلا للمستخدمين المسجلين لا يسمح بتعديل أو حذف الرسائل يسمح فقط بإضافة رسالة جديدة يتم التحقق أن userId في الرسالة يساوي المستخدم الحالي بهذا تحمي النظام من التخريب أو التلاعب. سابعًا: التبليغ والإشراف بما أن الشات مفتوح للعامة، من الأفضل: إضافة زر “إبلاغ عن رسالة” تخزين البلاغات في collection منفصل أو على الأقل تسجيل الرسائل المسيئة لمراجعتها لاحقًا ويمكنك لاحقًا إضافة مشرف لكل قرية. ثامنًا: الأداء وعدد الرسائل حتى لا يبطئ التطبيق: لا تحمل كل الرسائل دفعة واحدة حمّل آخر 50 أو 100 رسالة فقط وعند التمرير للأعلى، حمّل رسائل أقدم Firebase يدعم هذا الأسلوب بسهولة. تاسعًا: التوسّع مستقبلاً بعد نجاح النظام، يمكنك إضافة: إرسال صور رد على رسالة إشعارات عند وصول رسالة جديدة غرف دردشة حسب نوع الخدمة (نقل، كهرباء، مياه، إلخ) لكن في البداية ركّز على النص فقط. اقتباس
السؤال
Mustafa Frag
السلام عليكم
لدي تطبيق خدمي يعرض خدمات المدينة وأريد أن أضيف فيه غرف دردشة لكل قرية شات بسيط لكي يسأل الناس عن الخدمات المختلفة في المدينة ، ومعي قاعدة بيانات علي موقع firebase
2 أجوبة على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.