Home > Enterprise >  Firebase (Realtime Database) Multiple Queries
Firebase (Realtime Database) Multiple Queries

Time:10-25

I have a simple app with Firebase database (Realtime Database).

I know that I am using a non relational database. Not the best for complex queries.

example Database Structure


1. For example, if I want to find the recipes with

time:15 && name: "rice and eggs"... Is it possible?

I know that I can find the recipes with (time=15)

DatabaseReference ref = databaseReference.child("recipes");

Query filtro = ref.orderByChild("time").equalTo(15);

Is there a way to find recipe with

time:15 && name: rice and eggs... ?????? (multiple querie)

2. Another issue, I am saving ingredients in an arrayList.

arrayListIngredient = new ArrayList<Ingredient>();

int i = 0;

while (i < size){
  Ingredient ingredient = new Ingredient(ingredientName[i]);
  arrayListIngredient.add(ingredient);
  i  ;
}

Recipe recipe = new Recipe();

recipe.setTime(time);
recipe.setName(name);
recipe.setNameIngredient(arrayListIngredient);

DatabaseReference reference = databaseReference.child("recipe").push().setValue(recipe);

arrayList Database structure

Is there a way (query) to search recipes with specific ingredients if I store my data like this???

For example, I want to know the recipes whose ingredients are rice, tomato, onion.

CodePudding user response:

The simple answer is: no, this type of query isn't possible on Firebase. If you need this type of expressive query and want ad-hoc querying on your database, consider using a SQL database - those are much better suited for dynamic and ad-hoc queries.

To the specifics of your question:

  • Firebase Database queries can only order/filter on a single property. In many cases it is possible to combine the values you want to filter on into a single (synthetic) property. For an example of this and other approaches, see my answer here: Query based on multiple where clauses in Firebase
  • What you're showing in your screenshot is a set-like structure that you store as an array. That is not ideal for querying, and you should consider storing it as a map. For more on this, see my answer here: Firebase query if child of child contains a value

But even with those cases covered, I don't think what you want to accomplish is possible on Firebase Realtime Database without extensive data duplication and client-side processing. Hence my recommendation to consider using a SQL database.

CodePudding user response:

Honestly, the Realtime Database will be more of a headache in this use case if you wish to handle complex filtering at the database level. You could filter based on one aspect and then perform additional filters client-side to suit your UI.

If you wish to continue with Firebase, I would highly recommend Firestore instead. Your data structure would not have to change at all and you would be able to perform complex queries as you wish. The semantics are a bit different, but this is the equivalent query using Firestore:

import { collection, query, where } from "firebase/firestore";
import db from "./where/your/firebase/config/lives.js";

const recipesDatabase = collection(db, "cities");
const recipesByIngredient = query(recipesDatabase, where("time", "==", 15), where("ingredients", "array-contains", ["rice", "tomato", "onion"]));

The "array-contains" operator will find recipes using all of the listed ingredients. Alternatively, you can use "array-contains-any" which will query all recipes containing any of the searched ingredients. See Firestore docs regarding indexes to help facilitate this.

  • Related