skip to Main Content

I tried to fetch data from Firebase whose userEmail is not same as current userEmailId and whose bloodGroup is same as current userBlood ordered by documentId (descending). But no desired result.how to solve this

I tried the following code But no desired result( No donation request found).
print output is also null.

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final controller = Get.put(UserController());
  bool donationRequestsLoading = true;
  Map<String, dynamic> donationMap = {};

  Future<void> fetchDonationRequests() async {
    try {
      final userEmailID = controller.user.value.email;
      final userBlood = controller.user.value.bloodGroup;
      print('blood group: $userBlood');

      QuerySnapshot querySnapshot = await FirebaseFirestore.instance
          .collection("Requests")
          .where("status", isEqualTo: "Pending")
          .where("bloodGroup", isEqualTo: userBlood)
          .where("userEmail", isEqualTo: userEmailID)
          .orderBy(FieldPath.documentId, descending: true)
          .get();

      // Process data
      if (querySnapshot.docs.isNotEmpty) {
        DocumentSnapshot documentSnapshot = querySnapshot.docs.first;
        donationMap = documentSnapshot.data() as Map<String, dynamic>;
      } else {
        donationMap = {}; // No data available
      }
    } catch (e) {
      print("Error fetching donation requests: $e");
    } finally {
      setState(() {
        donationRequestsLoading = false;
      });
    }
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      fetchDonationRequests();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: Column(
          children: [
            const EPrimaryHeaderContainer(
              child: Column(
                children: [
                  EHomeAppBar(),
                  SizedBox(height: ESizes.spaceBtwInputFields),
                  BloodGroupandNextDonation(),
                  SizedBox(height: ESizes.spaceBtwSections),
                ],
              ),
            ),
            const RequestToBloodBank(),
            const SizedBox(height: 28),

            // Post blood request, donate blood, blood banks
            const Padding(
              padding: EdgeInsets.symmetric(horizontal: ESizes.defaultSpace),
              child: Column(
                children: [
                  Row(
                    children: [
                      PostBloodRequest(),
                      SizedBox(width: 12),
                      BloodBanks(),
                      SizedBox(width: 12),
                      DonateBlood(),
                    ],
                  ),
                  SizedBox(height: ESizes.spaceBtwInputFields),
                ],
              ),
            ),

            // Donation Requests Section
            ESectionHeading(
              title: 'Donation Requests',
              showActionButton: true,
              onPressed: () {
                Get.to(() => const DonationRequestsList());
              },
            ),
            const SizedBox(height: 1),

            donationRequestsLoading
                ? const Padding(
              padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
              child: EShimmerEffect(
                width: double.infinity,
                height: 110,
                radius: 16,
              ),
            )
                : donationMap.isEmpty
                ? const Center(
              child: Text(
                "No donation requests available.",
                style: TextStyle(fontSize: 16, color: Colors.grey),
              ),
            )
                : DonationRequests(donationMap: donationMap),
            const SizedBox(height: 10),
          ],
        ),
      ),
    );
  }
}

2

Answers


  1. Chosen as BEST ANSWER

    It's working now...

    @override void initState() { super.initState();

    // Listen to changes in the user controller's data
    ever(controller.user, (_) {
      final userBlood = controller.user.value.bloodGroup;
      final currentUserEmail = controller.user.value.email;
    
      if (userBlood != null && currentUserEmail != null) {
        fetchDonationRequests(userBlood, currentUserEmail);
      }
    });
    

    }

    Future fetchDonationRequests(String userBlood, String currentUserEmail) async { try { print('Fetching requests for blood group: $userBlood, excluding email: $currentUserEmail');

      QuerySnapshot querySnapshot = await FirebaseFirestore.instance
          .collection("Requests")
          .where("status", isEqualTo: "Pending")
          .where("bloodGroup", isEqualTo: userBlood)
          .orderBy(FieldPath.documentId, descending: true)
          .get();
    
      // Filter results to exclude the current user's email
      final filteredDocs = querySnapshot.docs.where((doc) {
        final data = doc.data() as Map<String, dynamic>;
        return data["userEmail"] != currentUserEmail;
      }).toList();
    
      if (filteredDocs.isNotEmpty) {
        donationMap = filteredDocs.first.data() as Map<String, dynamic>;
      } else {
        donationMap = {}; // No data available
      }
    } catch (e) {
      print("Error fetching donation requests: $e");
    } finally {
      setState(() {
        donationRequestsLoading = false;
      });
    }
    

    }


  2. Firestore doesn’t allow isNotEqualTo with orderBy directly, to handle ordering, you may need to structure your data differently or order the results after fetching them

    you can use the updated code, written below

      // Fetch documents where userEmail is not the current user's email
      QuerySnapshot querySnapshot = await FirebaseFirestore.instance
          .collection("Requests")
          .where("status", isEqualTo: "Pending")
          .where("bloodGroup", isEqualTo: userBlood)
          .where("userEmail", isNotEqualTo: userEmailID) // Exclude current user
          .get();
    
      // Process data
      donationRequests = querySnapshot.docs.map((doc) {
        return doc.data() as Map<String, dynamic>;
      }).toList();
    
      print("Fetched ${donationRequests.length} donation requests");
    } catch (e) {
      print("Error fetching donation requests: $e");
    } finally {
      setState(() {
        donationRequestsLoading = false;
      });
    }
    

    Instead of processing only the first document, all matching documents are stored in a list, check the code below

            // Post blood request, donate blood, blood banks
            const Padding(
              padding: EdgeInsets.symmetric(horizontal: ESizes.defaultSpace),
              child: Column(
                children: [
                  Row(
                    children: [
                      PostBloodRequest(),
                      SizedBox(width: 12),
                      BloodBanks(),
                      SizedBox(width: 12),
                      DonateBlood(),
                    ],
                  ),
                  SizedBox(height: ESizes.spaceBtwInputFields),
                ],
              ),
            ),
    
            // Donation Requests Section
            ESectionHeading(
              title: 'Donation Requests',
              showActionButton: true,
              onPressed: () {
                Get.to(() => const DonationRequestsList());
              },
            ),
            const SizedBox(height: 1),
    
            donationRequestsLoading
                ? const Padding(
                    padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
                    child: EShimmerEffect(
                      width: double.infinity,
                      height: 110,
                      radius: 16,
                    ),
                  )
                : donationRequests.isEmpty
                    ? const Center(
                        child: Text(
                          "No donation requests available.",
                          style: TextStyle(fontSize: 16, color: Colors.grey),
                        ),
                      )
                    : ListView.builder(
                        shrinkWrap: true,
                        physics: const NeverScrollableScrollPhysics(),
                        itemCount: donationRequests.length,
                        itemBuilder: (context, index) {
                          final request = donationRequests[index];
                          return DonationRequests(donationMap: request);
                        },
                      ),
            const SizedBox(height: 10),
          ],
        ),
      ),
    );
    

    dont forget to like if the code works 🙂

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search