Utilize FieldPath.documentId() from Firestore to access a nested object

Let me explain the structure of my data:

Each element contains a cluster object, and the cluster object includes a tags object with one or more tag objects.

This setup aligns with firebase's denormalized data structure, as outlined here. We implement multi-path updates and lookup tables to maintain data consistency, which is why tags cannot be an array!

I want to query based on the document ids within the nested tags object. I am aware that firestore.FieldPath.documentId() retrieves the document id and can be utilized in a query like this:

db.collection('elements').where(firestore.FieldPath.documentId(), 'in',  ["a element document id"]).get().then((res) => {
    console.log(res);
}).catch((err) => {
    console.log(err);
});

However, I aim to use it within a nested object like this:

db.collection('elements').where('cluster.tags.'+firestore.FieldPath.documentId(), 'in',  ["a element document id"]).get().then((res) => {
    console.log(res);
}).catch((err) => {
    console.log(err);
});

I did not anticipate my approach to work as expected, and I have not come across any examples of this. Although elements.cluster.tags serves as a valid FieldPath, how can I access the documentId() within a .where() query?

Any suggestions?

Answer №1

firestore.FieldPath.documentId() does not actually provide a document ID. Instead, it returns a FieldPath token object on the client side. This object cannot be used in string concatenation as it does not have a final string value on the client. The actual string value is only generated when interpreted on the server. Therefore, the current task you are attempting is not feasible. The API documentation for where() states that a FieldPath argument can only be passed when it is the first argument.

If you wish to create a path to a field, you must know its complete name. There are no wildcards or substitutions available for this purpose.

It seems that the structure of your data may not fulfill your query requirements. It appears that you require a specific field containing the IDs of tags you wish to locate within the document. You can achieve this by adding a new field of list type that includes strings of document ID tags. Subsequently, you can utilize an in query to determine if a document ID exists within that field in any document of the collection.

For instance:

db
    .collection('elements')
    .where('doc-tags', 'in', ["a element document id"])
    .get()

In this scenario, if 'doc-tags' consists of a list of tags, the query will retrieve all documents where any of the requested IDs are included.

Answer №2

If you're looking to achieve a specific outcome, this solution might be the one you're seeking. To clarify, my interpretation of your objective is to retrieve and log the properties of nested tags. It appears that you initially attempted to access a document but only managed to retrieve the collection. By utilizing the DOC method in conjunction with chaining, once the promise is fulfilled, you can leverage the resolved value (which will be a SnapShot of your tag document) and utilize the GET method to navigate through your tag's nested properties with the help of template strings. This allows for the incorporation of expressions to modify tagIDs dynamically.

db.collection('elements').doc('KKLWwFfdeKgS0viYonXb').get().then(res => {
    console.log(res.get(`cluster.tags.${tagID}`))//or as deeply nested as required
}).catch(err => console.log(err))

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The declaration file for the module 'react-tilt' was not located

After following the installation and import steps for react-tilt as outlined in this guide, I encountered the following error message and am unable to utilize it. I'm uncertain about what the message implies. Is there anyone who can help me resolve th ...

Explore the functionality of a TypeScript-created Vue component by testing it with Vue-test-utils

In my attempt to validate props with various data types in a Vue component (built using TypeScript), I utilized the Vue-test-utils package. Despite implementing expect().tobe(), there remains an untested line: DropDownList.vue <template> <v-sel ...

Prevent the 'unbound function' ESLint warning when supplying a static method reference to a superclass constructor in TypeScript

Looking to solve a technical problem in my code. I have a class that needs to call its superclass using a function passed as an argument. I specifically want to pass a static function from the same class: export abstract class ChildAdapter extends Adapter{ ...

How to set up an Angular ErrorHandler?

Attempted to register an Angular ErrorHandler in this simplified StackBlitz environment, but it seems that it's not capturing the error thrown within the constructor of the HelloComponent. Any insights on this issue? Your opinions? ...

The return type is not undefined but the switch covers all possibilities

I'm struggling to understand the issue with this simple example interface List { "A": false, "B": false, } // The function is missing a return statement and its return type does not include 'undefined'.ts(2366) / ...

Adding TH into a TABLE in Angular 2 by verifying TD elements

I am seeking a way to automatically generate thead and th, using td in the template : <Datatable> <tr #lineSelected *ngFor="let subscription of results"> <td nameColumn="Nom">{{subscription.name}}</td> <td n ...

Encountering errors: Time-zone discrepancies arise when making API calls from AngularJS and querying results from Firebase using NodeJS

Whenever I try to query with a date range, the results returned are incorrect. I have implemented DateRangePicker jQuery for selecting both date and time ranges. After that, I make an API call and send my date/Moment JS object to my Node.js API where I q ...

Shifting Angular Component Declarations to a New Location

Here's a question that might sound silly: In my Angular project, I am looking to reorganize my component declarations by moving them from angular.module.ts to modules/modules.modules.ts. The goal is to structure my src/app directory as follows: src ...

Listening for Internet Connection in Ionic and Angular

Currently, I am working on implementing a listener in my Ionic app that can detect changes in network activity and respond accordingly. import { Component } from '@angular/core'; import { Network } from '@capacitor/network'; @Component ...

Create an interactive and responsive user interface for Object using the Angular framework

After receiving a JSON Object from an API call with multiple string values, I need to create an Interface for this Object in the most efficient way possible. Rather than manually writing an Interface with 100 keys all of type string, is there a quicker a ...

Can you explain the distinction between needing ts-node and ts-node/register?

Currently, I am conducting end-to-end tests for an Angular application using Protractor and TypeScript. As I was setting up the environment, I came across the requirement to include: require("ts-node/register") Given my limited experience with Node.js, I ...

Tips for generating a hyperlink in a Typescript file using Angular version 16 and above

I am encountering an issue with my consts.ts file in the project. Specifically, I have defined a constant LINK1 as <a href='https://sample.com/'>LINK 1</a>; However, this setup is not working as expected. What I actually want is to d ...

Uncovering the mystery of retrieving form values from dynamic HTML in Angular 2

As a beginner in Angular 2, I am facing challenges extracting values from Dynamic HTML. My task involves having some Form Inputs and injecting Dynamic HTML within them that contain additional inputs. I followed the example by @Rene Hamburger to create the ...

Retrieving information from a .json file using TypeScript

I am facing an issue with my Angular application. I have successfully loaded a .json file into the application, but getting stuck on accessing the data within the file. I previously asked about this problem but realized that I need help in specifically und ...

Determining the type of index to use for an interface

Imagine having an interface called Animal, with some general properties, and then either be a cat or a dog with corresponding properties. interface Dog { dog: { sound: string; } } interface Cat { cat: { lives: number; } } type CatOrDog = Cat | D ...

Tips for adding a mat-error to a mat-input-field on-the-fly

To handle user input exceeding maxLength and dynamically add < mat-error > to the DOM in case of an error, I have implemented an attribute directive that enforces the character limit on input fields. This directive is used across multiple files in th ...

The declaration file for the datepicker module could not be located, even though the necessary types have been installed

I'm encountering an issue during production build on my Next.js project. The error message reads: Could not find a declaration file for module 'react-datepicker'. '../node_modules/react-datepicker/dist/index.js' implicitly has an ...

Retrieving the latest status array by index using Typescript in Angular

Need help with this code logic. I am working on an array and function : import { Component } from '@angular/core'; @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: [ './app.compon ...

What is the best method for showcasing organized data with select and optgroup in Angular?

Searching for a way to create a grouped dropdown select using Angular? In this case, the group is based on the make property. const cars = [{ make: "audi", model: "r8", year: "2012" }, { ...

The Enigmatic Essence of TypeScript

I recently conducted a test using the TypeScript code below. When I ran console.log(this.userList);, the output remained the same both times. Is there something incorrect in my code? import { Component } from '@angular/core'; @Component({ sel ...