I have been trying to get data from Firebase (using Angular).
Program summary
It's a small app to store meal recipes, their ingredients to generate cumulated shopping list based on meal planning - daily, weekly, etc.
What I have:
1. Firebase database structure (fragment of it)
Ingredients (collection)
Id: string
Name: string
Tags: array of string
Recipes (collection)
CreatedOn: Timestamp
MealTitle: string
MealType: string
Method: string
RecipeIngredients (subcollection)
Id: string
IngredientId: string
ExtendedDescription: string
QTY: number
UOM: string
As you can see Recipes collection contains RecipeIngredients sub-collection which has IngredientId from Ingredients collection and some additional data.
2. Method for getting list of ingredients from RecipeIngredients sub-collection for specific recipe
getRecipeIngredients(recipeId: string): Observable<RecipeIngredient[]> {
this.recipesCollection = this.afs.collection('Recipes', ref => ref.orderBy('CreatedOn', 'desc'));
this.recipeIngredients = this.recipesCollection.doc(recipeId).collection('RecipeIngredients').snapshotChanges().pipe(
map(changes => {
return changes.map(action => {
const data = action.payload.doc.data() as RecipeIngredient;
data.Id = action.payload.doc.id;
return data;
})
})
)
return this.recipeIngredients;
}
3. Method for getting specific ingredient based on its Id
getIngredientById(ingredientId: string): Observable<Ingredient> {
this.ingredientDoc = this.afs.doc<Ingredient>(`Ingredients/${ingredientId}`);
this.ingredient = this.ingredientDoc.snapshotChanges().pipe(
map(action => {
if (action.payload.exists === false) {
return null;
} else {
const data = action.payload.data() as Ingredient;
data.Id = action.payload.id;
return data;
}
})
)
return this.ingredient;
}
4. What I want to achieve
I want to display a list of ingredients for specific recipe in a table containing columns: Ingredient Name, Extended Description, QTY, UOM. The thing is I cannot figure out how to get Ingredient name. Reasonable solution for me is to do it inside getRecipeIngredients an extend its returning result by that field or by whole Ingredients collection. I tried RxJS operators like mergeFlat or combineLatest but I got stuck.
I could of course change the database structure but that is also a learning project for me. I believe I'll have this kind of challenge sooner or later.