اذهب إلى المحتوى
  • 0

كيفية دمج البيانات من مصادر مختلفة في Firebase؟

Flutter Dev

السؤال

تحيه طيبه للجميع 

انا جديد على الفايربيز وحسب الذي فهمته انني لا استطيع استعمل left join  في الفايربيز عكس قواعد mysql  والان أحاول ان احصل على بعض البيانات من جداول مختلفة بطريقة تكون قريبه من left join 

قمت بعمل هذا الكود:
 

Future<void> _fetchData() async {
    final FirebaseFirestore firestore = FirebaseFirestore.instance;

    // Fetch the first query snapshot and extract the value of 'TopicState'
    final QuerySnapshot topicsSnapshot = await firestore
        .collection('topics')
        .where('id', isEqualTo: widget.PostID)
        .get();
    final int topicState =
    topicsSnapshot.docs.isNotEmpty ? topicsSnapshot.docs.first.get('Id_Sub_Category') : null;

    
    final QuerySnapshot subCategorySnapshot =
    await firestore.collection('Sub_Category').where('idSubCat', isEqualTo: topicState).get();


    final List<FullListWomanModel> data = [];
    if (topicsSnapshot.docs.isNotEmpty) {
      data.addAll(topicsSnapshot.docs.map((doc) => FullListWomanModel.fromJson(doc.data() as Map<String, dynamic>)).toList());
    }
    if (subCategorySnapshot.docs.isNotEmpty) {
      data.addAll(subCategorySnapshot.docs.map((doc) => FullListWomanModel.fromJson(doc.data() as Map<String, dynamic>)).toList());
    }

    setState(() {
      _ListDataDisplay = data;
    });
  }

الهدف منه هو الاستعلام من الجدول الأساسي وهو جدول topics ثم الحقول التي تحتوي على ارقام فريدة لجداول مختلفة احصل على بياناتها ايضا الكود يعمل ولكن مشكلتي الان انني احصل على قائمتين في وقت تشغيل الكود بمعنى كل collection  في الأعلى يعمل ك قائمة منفصلة ولا يتم دمج بياناتهما كيف احصل على قائمة واحد بتفاصيل collection الأول وثاني مدموجة 

كيف يمكن حل هذا المشكلة لمن لديه خبره في الامر؟ ولكم جزيل الشكر

تم التعديل في بواسطة Mustafa Suleiman
تعديل عنوان السؤال
رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 1

تم التوضيح من قبل عزيزي،  يمكنك دمج البيانات المسترجعة من الجدولين في نفس القائمة باستخدام الدالة addAll() في مكانين مختلفين في الكود.

هناك عدة طرق للقيام بذلك وهذا مثال لكيفية الدمج:

Future<void> _fetchData() async {
    final FirebaseFirestore firestore = FirebaseFirestore.instance;

    // Fetch the first query snapshot and extract the value of 'TopicState'
    final QuerySnapshot topicsSnapshot = await firestore
        .collection('topics')
        .where('id', isEqualTo: widget.PostID)
        .get();
    final int topicState =
    topicsSnapshot.docs.isNotEmpty ? topicsSnapshot.docs.first.get('Id_Sub_Category') : null;

    
    final QuerySnapshot subCategorySnapshot =
    await firestore.collection('Sub_Category').where('idSubCat', isEqualTo: topicState).get();


    final List<FullListWomanModel> data = [];

    if (topicsSnapshot.docs.isNotEmpty) {
      data.addAll(topicsSnapshot.docs.map((doc) => FullListWomanModel.fromJson(doc.data() as Map<String, dynamic>)).toList());
    }

    if (subCategorySnapshot.docs.isNotEmpty) {
      // Loop over the documents of the Sub_Category collection and check if the document already exists in the data list to avoid duplication
      subCategorySnapshot.docs.forEach((doc) {
        final FullListWomanModel model = FullListWomanModel.fromJson(doc.data() as Map<String, dynamic>);
        if (!data.contains(model)) {
          data.add(model);
        }
      });
    }

    setState(() {
      _ListDataDisplay = data;
    });
}

الكود يقوم بإضافة جميع الوثائق التي تم العثور عليها في الجدول الثاني Sub_Category إلى القائمة data، ولكنه يتحقق أيضًا مما إذا كانت الوثيقة موجودة بالفعل في القائمة الرئيسية لتجنب التكرار والحفاظ على وجود عناصر فريدة في القائمة المدمجة النهائية.

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 1

حاول تجربة الحل التالي:

  1. استخدم الحقل الفريد في جدول الـ "topics" للوصول إلى جدول الـ "Sub_Category" ، وذلك باستخدام دالة الـ "join".
  2. اجمع البيانات التي تحتاجها في مصفوفة واحدة باستخدام الدالة "addAll" كما هو موضح في الكود الحالي الخاص بك.
  3. ثم، تستطيع استخدام الدالة "sort" لفرز المصفوفة بناءً على الوقت الذي تم الحصول عليه من كل جدول.

ليصبح الكود بعد التعديل كالتالي:

Future<void> _fetchData() async {
  final FirebaseFirestore firestore = FirebaseFirestore.instance;

  final QuerySnapshot topicsSnapshot = await firestore
      .collection('topics')
      .where('id', isEqualTo: widget.PostID)
      .get();
  final int topicState =
      topicsSnapshot.docs.isNotEmpty ? topicsSnapshot.docs.first.get('Id_Sub_Category') : null;

  final QuerySnapshot subCategorySnapshot = await firestore
      .collection('Sub_Category')
      .where('idSubCat', isEqualTo: topicState)
      .get();

  final List<FullListWomanModel> data = [];

  // 1. دمج الجدولين بإستخدام join
  if (topicsSnapshot.docs.isNotEmpty && subCategorySnapshot.docs.isNotEmpty) {
    final List<QuerySnapshot> snapshots = await Future.wait([
      firestore.collection('topics').where('id', isEqualTo: widget.PostID).get(),
      firestore
          .collection('Sub_Category')
          .where('idSubCat', isEqualTo: topicState)
          .get(),
    ]);

    final List<FullListWomanModel> topics = snapshots[0].docs.map((doc) =>
        FullListWomanModel.fromJson(doc.data() as Map<String, dynamic>)).toList();
    final List<FullListWomanModel> subCategories = snapshots[1].docs.map((doc) =>
        FullListWomanModel.fromJson(doc.data() as Map<String, dynamic>)).toList();

    // 2. إضافة البيانات إلى مصفوفة واحدة باستخدام addAll
    data.addAll(topics);
    data.addAll(subCategories);

    // 3. فرز المصفوفة بناءً على الوقت الذي تم الحصول عليه من كل جدول
    data.sort((a, b) => b.time.compareTo(a.time));
  }

  setState(() {
    _ListDataDisplay = data;
  });
}

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 1

قمت بتعديل الكود لك ليصبح مختصرًا أكثر ويحصل على نفس البيانات بشكل أكثر فعالية، وتستطيع استخدام الدالة "sort" بعد ذلك إذا رغبت في فرز البيانات.

Future<void> _fetchData() async {
  final FirebaseFirestore firestore = FirebaseFirestore.instance;

  final QuerySnapshot subCategorySnapshot = await firestore
      .collection('Sub_Category')
      .where('idSubCat',
          isEqualTo: (await firestore
                  .collection('topics')
                  .where('id', isEqualTo: widget.PostID)
                  .get())
              .docs
              .first
              .get('Id_Sub_Category'))
      .get();

  final List<FullListWomanModel> data = [];

  if (subCategorySnapshot.docs.isNotEmpty) {
    final List<FullListWomanModel> subCategories = subCategorySnapshot.docs
        .map((doc) => FullListWomanModel.fromJson(doc.data() as Map<String, dynamic>))
        .toList();

    data.addAll(subCategories);
  }

  setState(() {
    _ListDataDisplay = data;
  });
}

وإليك شرح مختصر، الكود يستخدم Firebase للاستعلام عن بيانات من جداول مختلفة ودمجها في مصفوفة واحدة.

وذلك من خلال استخدام الحقل الفريد في جدول الـ "topics" للوصول إلى جدول الـ "Sub_Category" باستخدام دالة الـ "join" ، ثم جمع البيانات التي تحتاجها في مصفوفة واحدة باستخدام الدالة "addAll".

وتستطيع الاستغناء عن sort فأنت لست بحاجة إليها بالنسبة لسؤالك.

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 1

حاول تنفيذ التالي : 

استخدام قيمة مشتركة بين الجدولين (idSubCat) لدمج البيانات في القائمة، بعد دمج البيانات ، وإضافة القائمة المدموجة إلى القائمة الرئيسية التي تحتوي على جميع البيانات.

Future < void > _fetchData() async {
    final FirebaseFirestore firestore = FirebaseFirestore.instance;

    final QuerySnapshot subCategorySnapshot = await firestore
        .collection('Sub_Category')
        .where('idSubCat',
            isEqualTo: (await firestore
                .collection('topics')
                .where('id', isEqualTo: widget.PostID)
                .get())
            .docs
            .first
            .get('Id_Sub_Category'))
        .get();

    final List < FullListWomanModel > data = [];

    if (subCategorySnapshot.docs.isNotEmpty) {
        final List < FullListWomanModel > subCategories = subCategorySnapshot.docs
            .map((doc) => FullListWomanModel.fromJson(doc.data() as Map < String, dynamic > ))
            .toList();
        data.addAll(subCategories);
    }

    final QuerySnapshot topicsSnapshot = await firestore
        .collection('topics')
        .where('id', isEqualTo: widget.PostID)
        .get();

    if (topicsSnapshot.docs.isNotEmpty) {
        final List < FullListWomanModel > topics = topicsSnapshot.docs
            .map((doc) => FullListWomanModel.fromJson(doc.data() as Map < String, dynamic > ))
            .toList();
        // Merge the two lists based on a common field
        final Map < int, FullListWomanModel > mergedData = {};
        for (final topic in topics) {
            mergedData[topic.id] = topic;
        }
        for (final subCategory in subCategories) {
            mergedData[subCategory.idSubCat] = subCategory;
        }
        final List < FullListWomanModel > mergedList = mergedData.values.toList();

        data.addAll(mergedList);
    }
    setState(() {
        _ListDataDisplay = data;
    });
}

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 11 دقائق مضت قال Mustafa Suleiman:

حاول تجربة الحل التالي:

  1. استخدم الحقل الفريد في جدول الـ "topics" للوصول إلى جدول الـ "Sub_Category" ، وذلك باستخدام دالة الـ "join".
  2. اجمع البيانات التي تحتاجها في مصفوفة واحدة باستخدام الدالة "addAll" كما هو موضح في الكود الحالي الخاص بك.
  3. ثم، تستطيع استخدام الدالة "sort" لفرز المصفوفة بناءً على الوقت الذي تم الحصول عليه من كل جدول.

ليصبح الكود بعد التعديل كالتالي:

Future<void> _fetchData() async {
  final FirebaseFirestore firestore = FirebaseFirestore.instance;

  final QuerySnapshot topicsSnapshot = await firestore
      .collection('topics')
      .where('id', isEqualTo: widget.PostID)
      .get();
  final int topicState =
      topicsSnapshot.docs.isNotEmpty ? topicsSnapshot.docs.first.get('Id_Sub_Category') : null;

  final QuerySnapshot subCategorySnapshot = await firestore
      .collection('Sub_Category')
      .where('idSubCat', isEqualTo: topicState)
      .get();

  final List<FullListWomanModel> data = [];

  // 1. دمج الجدولين بإستخدام join
  if (topicsSnapshot.docs.isNotEmpty && subCategorySnapshot.docs.isNotEmpty) {
    final List<QuerySnapshot> snapshots = await Future.wait([
      firestore.collection('topics').where('id', isEqualTo: widget.PostID).get(),
      firestore
          .collection('Sub_Category')
          .where('idSubCat', isEqualTo: topicState)
          .get(),
    ]);

    final List<FullListWomanModel> topics = snapshots[0].docs.map((doc) =>
        FullListWomanModel.fromJson(doc.data() as Map<String, dynamic>)).toList();
    final List<FullListWomanModel> subCategories = snapshots[1].docs.map((doc) =>
        FullListWomanModel.fromJson(doc.data() as Map<String, dynamic>)).toList();

    // 2. إضافة البيانات إلى مصفوفة واحدة باستخدام addAll
    data.addAll(topics);
    data.addAll(subCategories);

    // 3. فرز المصفوفة بناءً على الوقت الذي تم الحصول عليه من كل جدول
    data.sort((a, b) => b.time.compareTo(a.time));
  }

  setState(() {
    _ListDataDisplay = data;
  });
}

 

اهلا اخي الكريم

شاكر لك ردك اخي العزيز

توجد مشكلة أخي انا ليس لدي حقل في قاعدة البيانات اسمه time كيف يمكن تعريف هذا المتغير؟

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 15 دقائق مضت قال Mustafa Suleiman:

قمت بتعديل الكود لك ليصبح مختصرًا أكثر ويحصل على نفس البيانات بشكل أكثر فعالية، وتستطيع استخدام الدالة "sort" بعد ذلك إذا رغبت في فرز البيانات.

Future<void> _fetchData() async {
  final FirebaseFirestore firestore = FirebaseFirestore.instance;

  final QuerySnapshot subCategorySnapshot = await firestore
      .collection('Sub_Category')
      .where('idSubCat',
          isEqualTo: (await firestore
                  .collection('topics')
                  .where('id', isEqualTo: widget.PostID)
                  .get())
              .docs
              .first
              .get('Id_Sub_Category'))
      .get();

  final List<FullListWomanModel> data = [];

  if (subCategorySnapshot.docs.isNotEmpty) {
    final List<FullListWomanModel> subCategories = subCategorySnapshot.docs
        .map((doc) => FullListWomanModel.fromJson(doc.data() as Map<String, dynamic>))
        .toList();

    data.addAll(subCategories);
  }

  setState(() {
    _ListDataDisplay = data;
  });
}

وإليك شرح مختصر، الكود يستخدم Firebase للاستعلام عن بيانات من جداول مختلفة ودمجها في مصفوفة واحدة.

وذلك من خلال استخدام الحقل الفريد في جدول الـ "topics" للوصول إلى جدول الـ "Sub_Category" باستخدام دالة الـ "join" ، ثم جمع البيانات التي تحتاجها في مصفوفة واحدة باستخدام الدالة "addAll".

وتستطيع الاستغناء عن sort فأنت لست بحاجة إليها بالنسبة لسؤالك.

اهلا بك اخي الكريم

الكود يعمل الان ولكن توجد مشكله بسيطة الكود يجلب فقط بيانات Sub_Category اما بيانات كولكشن توبكس لا تاتي 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 48 دقائق مضت قال Mustafa Suleiman:

حاول تنفيذ التالي : 

استخدام قيمة مشتركة بين الجدولين (idSubCat) لدمج البيانات في القائمة، بعد دمج البيانات ، وإضافة القائمة المدموجة إلى القائمة الرئيسية التي تحتوي على جميع البيانات.

تقوم هذه الوظيفة بالحصول على بيانات من جدولين مختلفين ودمجهما في قائمة واحدة. يتم استخدام قيمة مشتركة بين الجدولين (idSubCat) لدمج البيانات في القائمة. بعد دمج البيانات ، يتم إضافة القائمة المدموجة إلى القائمة الرئيسية التي تحتوي على جميع البيانات.



 

 غريبه هنا نوصل الى نفس النتيجة انا احصل على البيانات بشكل منفصل او قائمتين الان مع اخر تعديل ارسلته

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...