capawesome-team / capacitor-firebase

⚡️ Firebase plugins for Capacitor. Supports Android, iOS and the Web.

Home Page:https://capawesome.io/plugins/firebase/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

bug: Firestore compositeFilter 'and' is not working

aliexalter opened this issue · comments

Plugin(s)

  • Analytics
  • App
  • App Check
  • Authentication
  • Crashlytics
  • Cloud Firestore
  • Cloud Messaging
  • Cloud Storage
  • Performance
  • Remote Config

Version

5.4.0

Platform(s)

  • Android
  • iOS
  • Web

Current behavior

const monthData = await FirebaseFirestore.getCollection({
        reference: 'users/docs/entries',
        compositeFilter:{
          type: 'and',
          queryConstraints: [
            {
              type: 'where',
              fieldPath: 'Year',
              opStr: '==',
              value: format(this.currentDate, "yyyy")
            },
            {
              type: 'where',
              fieldPath: 'Month',
              opStr: '==',
              value: format(this.currentDate, "MM")
            }
          ]
        }
      });

When I change this.currentDate by adding year it returns same result for example
this.currentDate Year == 2024, Month == 02 return the 2 results suppose A,B
When I change to
this.currentDate Year == 2023, Month == 02 it still return results A,B where as there is no record which has year 2023

Expected behavior

It should return empty [] snapshot which it can return when only Month is changed

Reproduction

Make a collection in Firebase Firestore with two fields and then query using compositeFilter

Steps to reproduce

Make a collection in Firebase Firestore with two fields and then query using compositeFilter.

Other information

No response

Capacitor doctor

💊 Capacitor Doctor 💊

Latest Dependencies:

@capacitor/cli: 5.7.0
@capacitor/core: 5.7.0
@capacitor/android: 5.7.0
@capacitor/ios: 5.7.0

Installed Dependencies:

@capacitor/cli: 6.0.0-rc.0
@capacitor/core: 6.0.0-rc.0
@capacitor/android: 6.0.0-rc.0
@capacitor/ios: 6.0.0-rc.0

[success] iOS looking great! 👌
[success] Android looking great! 👌

Before submitting

  • I have read and followed the bug report guidelines.
  • I have attached links to possibly related issues and discussions.
  • I understand that incomplete issues (e.g. without reproduction) are closed.

Note: Year and Month Fields are strings in Firestore collection documents

I think problem is here where it uses FieldPath for Field too
Screenshot 2024-02-14 at 3 14 27 PM
in above scenario
fieldPath: 'Year' is actually a Field
fieldPath: 'Month' is actually a Field
FieldPath looks for documentID and there is no document with id 'Year' or 'Month'

OR

Filter.and() is being used twice like Filter.and(Filter.and())

I just tested this on Android and i can not reproduce the issue. Make sure that format(this.currentDate, "yyyy") and format(this.currentDate, "MM") outputs what you expect.

This issue has been labeled as needs: reproduction. This label is added to issues that need a code reproduction.

Please provide a Minimal, Reproducible Example using this template in a public GitHub repository so we can debug the issue.

If you have already provided a code snippet and are seeing this message, it is likely that the code snippet was not enough for us to reproduce the issue.

monthly.page.ts

import { Component, OnInit } from '@angular/core';
import { addMonths, addYears, format } from 'date-fns';
import { AuthenticationService } from 'src/app/services/authentication.service';
import { FirebaseFirestore } from '@capacitor-firebase/firestore';

Component({
  selector: 'app-monthly',
  templateUrl: './monthly.page.html',
  styleUrls: ['./monthly.page.scss'],
})
export class MonthlyPage implements OnInit {
public s_year:number = 0; //use for UI
  public s_month:string = ''; //use for UI
  private currentDate = new Date();
  public entries:any[] = [];

async ngOnInit() {
    this.s_year = this.currentDate.getFullYear();
    this.s_month = format(this.currentDate, 'MMMM');
  }

async ionViewWillEnter() {
    await this.loadCurrentMonthData();
  };

async prevYear() {
    this.currentDate = addYears(this.currentDate, -1);
this.s_year = this.currentDate.getFullYear();
    await this.loadCurrentMonthData();
  };
  async nextYear() {
    this.currentDate = addYears(this.currentDate, +1);
this.s_year = this.currentDate.getFullYear();
    await this.loadCurrentMonthData();
  };
  async prevMonth() {
    this.currentDate = addMonths(this.currentDate, -1);
this.s_month = format(this.currentDate, 'MMMM');
    await this.loadCurrentMonthData();
  };
  async nextMonth() {
    this.currentDate = addMonths(this.currentDate, +1);
this.s_month = format(this.currentDate, 'MMMM');
    await this.loadCurrentMonthData();
  };
  async loadCurrentMonthData() {
     console.log("loadCurrentMonthData", this.currentDate, format(this.currentDate, "yyyy"), format(this.currentDate, "MM"));
   this.entries = [];
      const monthData = await FirebaseFirestore.getCollection({
        reference: 'users/docs/entries',
        compositeFilter:{
          type: 'and',
          queryConstraints: [
            {
              type: 'where',
              fieldPath: 'Year',
              opStr: '==',
              value: format(this.currentDate, "yyyy")
            },
            {
              type: 'where',
              fieldPath: 'Month',
              opStr: '==',
              value: format(this.currentDate, "MM")
            }
          ]
        }
      });
      if(monthData.snapshots.length > 0)
      {
        monthData.snapshots.forEach((doc:any) => {
          let entry:any = doc.data;
          entry.id = doc.id;
          this.entries.push(entry);
        });
      }
  };
};

monthly.page.html

<ion-content [fullscreen]="true">
  <ion-grid>
    <ion-row class="yearChange">
      <ion-col>
        <ion-icon name="arrow-back" (click)="prevYear()"></ion-icon>
      </ion-col>
      <ion-col class="ion-text-center">
        <strong>{{s_year}}</strong>
      </ion-col>
      <ion-col>
        <ion-icon class="ion-float-right" name="arrow-forward" (click)="nextYear()"></ion-icon>
      </ion-col>
    </ion-row>
    <ion-row class="monthChange">
      <ion-col>
        <ion-icon name="arrow-back" (click)="prevMonth()"></ion-icon>
      </ion-col>
      <ion-col class="ion-text-center">
        <strong>{{s_month}}</strong>
      </ion-col>
      <ion-col>
        <ion-icon class="ion-float-right" name="arrow-forward" (click)="nextMonth()"></ion-icon>
      </ion-col>
    </ion-row>
</ion-grid>
</ion-content>

Here is the Firestore data screenshot
Screenshot 2024-02-14 at 4 20 14 PM

create at least 3 documents inside entries which have Fields with same Month:"02" and Year: "2024"

Unfortunately, my time is limited and I can only work on issues that are sufficiently prepared.

As described above, please provide a Minimal, Reproducible Example using this template in a public GitHub repository so we can debug the issue.

Just add two buttons to this minimal, reproducible example:

  1. Set document
  2. Get document

Here is the repo
https://github.com/aliexalter/capacitor-firestore-test

  • git clone
  • npm install
  • npx cap sync android

@aliexalter Please provide a public repository. Maybe someone else will have a similar problem in the future and take a look at this conversation and the code.

@robingenz its public now sorry for inconvenience

I still can't reproduce your issue. Everything seems to be working as expected.

grafik

I also tested it with my own (empty) Firebase project:

grafik

Have you try changing the Year value in composite query? it should not return 2025 or 2023 result it will be empty. But still return the results.

Check the log when changing year by tapping prev and next buttons

Thank you for pointing that out. I've just created a fix: #562