Firebase Realtime Database – اضافة واستقبال البيانات من قاعدة البيانات
في هذا الدرس سوف يتم شرح طريق التعامل مع Firebase Realtime Database لاضافة البيانات واستقبالها بابسط طريقة ممكنة, هنالك اكثر من طريقة للاضافة اللقاعدة والاستقبال منها وتختلف الطريقة حسب البيانات المرسلة والمستقبل وايضا تختلف الطرق من مبرمج لاخر بما يراه مناسباً.. الشرح سوف يتم باستخدام لغة Kotlin
الاضافات التي سوف نعمل عليها
-
اضافة مكتبة Firebase Database
-
حفظ معلومات المستخدم في قاعدة البيانات كـ key, value عن طريق hashMap
-
استقبال البيانات التي تم حفظها عن طريق Model
-
استقبال key, value لمعرفة البيانات عن طريق key
-
العمل على استقبال كامل البيانات من القاعدة مع اختلافهم
العمل سوف يكون في نفس المشروع السابق سوف نضيف زر لارسال البيانات وزر لاستقبالهم وننشئ function لجلب البيانات واخرى لاستقبالهم
اولاً نقوم باضافة المكتبة ال ملف gradle
1 |
implementation 'com.google.firebase:firebase-database:16.0.1' |
ملاحظة سوف يتم العمل على المشروع السابق لذالك سوف يكون العمل بعد تسجيل من المستخدم لتطبيق نقوم باخذ الايميل الخاص به واسمه و user id وحفظهم في قاعدة بيانات الفايربيس
الان العمل عىل اضافة البيانات الى قاعدة البيانات وانشاء دالة pushData
- اولاً نقوم باستدعاء FirebaseDatabase.getInstance().reference
- ثانياً نقوم بأنشاء HashMap والقيم سوف تكون String key, value
- ثالثاً اضافة البيانات الى hashMap كـ key, value
- رابعاً تحديد المكان الذي نريد حفظ البيانات به في القاعدة ووبحالتنا سوف يكون داخل users وحفظ بيانات كل مستخدم عن طريق user id الخاص به
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
private fun pushData(view: View) { try { val ref = FirebaseDatabase.getInstance().reference val myHashMap = HashMap<String, String>() myHashMap.put("userName", auth!!.currentUser!!.displayName.toString()) myHashMap.put("userEmail", auth!!.currentUser!!.email.toString()) myHashMap.put("userID", auth!!.currentUser!!.uid) ref.child("users/user-${auth!!.uid}").setValue(myHashMap) showMessage(view, "add Successful") } catch (e: Exception) { Log.e(TAG, "Error ${e.localizedMessage}") } } |
تمرير View هوا فقط لاظهار رسالة عن طريق function
1 2 3 |
private fun showMessage(view: View, message: String) { Snackbar.make(view, message, Snackbar.LENGTH_INDEFINITE).setAction("FIRE", null).show() } |
عند الضغط على Add For Firebase Data سوف يتم حفظ بيانات المستخدم “اذا تم التسجيل عن طريق الايميل وكلمة مرور سوف تكون قيمة الاسم null لانه لم نأخذ الاسم اما عن طريق google يتم جلب اسم الحساب”
النتيجة
تم حفظ البيانات في القاعدة لدينا بنجاح وطبعاً كل يوزر جديد سوف يحفظ بيانات فقط سوف يختلف id الخاص به
الان لنجرب تسجيل عن طريق الاميل وكلمة المرور ونحفظ البيانات لنرا النتيجة
نلاحظ انه ايضا تم الحفظ ولكن الاسم كانت قيمته null لانه المستخدم سجل عن طريق كلمة مرور والايميل
الان سوف نعمل على جلب البيانات من القاعدة عن طريق model يتم انشائه باسماء ال key الموجودة وبحالتنا لدينا userEmail, userID, userName
أيضاً هنالك اكثر من طريق لانشاء الكلاس ولكن سوف نستخدم طريقة سهلة وواضحة
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class UserModel { var userName: String? = null get() = field set(value) { field = value } var userEmail: String? = null get() = field set(value) { field = value } var userID: String? = null get() = field set(value) { field = value } } |
ويمكنك زيارة موقع Kotlin الرسمي لمعرفة المزيد عن Getters and Setters اضغط هنا
الان سوف نقوم باستقبال بيانات المستخدم من جديد داخل التطبيق سوف نقوم بانشاء function
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
private fun getData() { val ref1 = FirebaseDatabase.getInstance().getReference("users") ref1.addListenerForSingleValueEvent(object : ValueEventListener { override fun onCancelled(snapshot: DatabaseError) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. Log.i(TAG, snapshot.message) } override fun onDataChange(snapshot: DataSnapshot) { val children = snapshot.children children.forEach { Log.i(TAG, it.key) Log.i(TAG, it.value.toString()) } } }) } |
قمنا بجلب البيانات وعرضها كـkey , value داخل forEach
الان سوف نستخدم model لجلب البيانات بطريقة منظمة اكثر حتى نستطيع استخدامها داخل التطبيق كما نريد
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
private fun getData() { val ref1 = FirebaseDatabase.getInstance().getReference("users") ref1.addListenerForSingleValueEvent(object : ValueEventListener { override fun onCancelled(snapshot: DatabaseError) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. Log.i(TAG, snapshot.message) } override fun onDataChange(snapshot: DataSnapshot) { for (keySnapshot in snapshot.children) { val user = keySnapshot.getValue(UserModel::class.java) Log.i(TAG, user?.userName) Log.i(TAG, user?.userEmail) Log.i(TAG, user?.userID) } } }) } |
نفس الكود السابق تقريباً ولكن نقوم بتمرير البيانات الى class model حتى نستطيع استخدام القيم فقط
وفي العرض Log نقوم بعرض معلوماته
بحالتنا حددنا مسار من داخل users ولكن ماذا اذا كان هنالك اكثر من جدول مثلاً users, post واكثر ايضا ما طريقة لجلب البيانات الخاص بهم ؟
بهذه الحالة لن نحدد المسار الى users بل سوف نقوم بجلب كامل المسارات الموجودة لدينا وجلب القيم داخلهم
الان سوف نعمل على جلب البيانات المسارات والقيم التي داخلها حتى نستطيع جلب كامل البيانات في الداتا لدينا
داخل دالة onDataChange نمسح القديم ونضيف التالي
1 2 3 4 5 6 |
val children = snapshot!!.children //يقوم برجوع عدد المسارات الموجود لدينا بشكل اساسي println("count: "+snapshot.children.count().toString()) children.forEach { println(it.toString()) } |
لمعرفة عدد المسارات الموجودة اذا كان يلزم الامر
اما لجلب كامل البيانات key, value
نقوم بتعديل الكود لدينا ليصبح
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
private fun getData() { val ref1 = FirebaseDatabase.getInstance().reference ref1.addListenerForSingleValueEvent(object : ValueEventListener { override fun onCancelled(snapshot: DatabaseError) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. Log.i(TAG, snapshot.message) } override fun onDataChange(snapshot: DataSnapshot) { for (keySnapshot in snapshot.children) { for (ch in snapshot.child(keySnapshot.key.toString()).children) { val key = ch.key val value = ch.value Log.i(TAG, value.toString()) } } } }) } |
اول for نقوم بجلب السمارات وال for الداخلية لجلب البيانات منها كـ قيم ومفتاح
يتم جلب المسار عن طريق keySnapshot.key.toString() وهنى ممكن عمل له فحص مثلاً اذا كان users نقوم باستقبال البيانات داخل model class
واذا كان غير مسار نستقبل داخل عن طريق model اخر حسب الشيئ الموجود في القاعدة لدينا
هذه الطريقة بشكل عام للاضافة وجلب البيانات مع تعدد المسارات وطبعاً ليست هيا الطريقة الوحيدة ولكن حسب الشيئ المطلوب لدينا نستطيع تحديد الطريقة الانسب لنا
الكود تجده كاملاً على GitHub