What is the proper way to implement the useFirestore() wrapper in VueUse?

I have implemented the useFirestore() wrapper from VueUse.org and am encountering an issue while typing the user ref it returns as User. Here is my code:

import { User } from 'src/types';
const userId = useUserStore().user.id;
const userDocRef = doc(db, 'users', userId);
const user = useFirestore<User>(userDocRef); // <-- Error shows here

This is what my User interface looks like:

export interface User {
  id: string;
  userType?: UserType;
  createdAt?: Timestamp;
  email?: string;
  displayName?: string;
  firstName?: string;
  lastName?: string;
  initials?: string;
  passwordUpdatedAt?: Timestamp;
  photoUrl?: string;
  phoneE164Format?: string;
  phoneNationalFormat?: string;
  stripeId?: string;
  stripeLink?: string;
  googleTokens?: {
    access_token: string;
    expiry_date: number;
    id_token: string;
    refresh_token: string;
    token_type: string;
  };
}

Although I now have intellisense with User properties for the user variable, I am getting an error on userDocRef:

No overload matches this call. Overload 1 of 4, '(maybeDocRef: MaybeRef<DocumentReference>, initialValue?: User | undefined, options?: UseFirestoreOptions | undefined): Ref<...>', gave the following error. Overload 2 of 4, '(maybeDocRef: MaybeRef<Query>, initialValue?: User[] | undefined, options?: UseFirestoreOptions | undefined): Ref<...>', gave the following error.ts(2769)

I have checked the "Type Declarations" section at the bottom of the useFirestore() documentation which might provide some insight. However, I am struggling to fully understand it.

I believe I am passing User correctly as a generic, so I am unsure why this error is occurring. Can someone please explain why this error is happening and how to resolve it?

Answer №1

After some investigation, I was able to solve the issue.

The conflict stemmed from a required id property in my interface.

Here is the revised code snippet with the necessary changes:

const userId = useUserStore().user.id;
const userDocRef = doc(db, 'users', userId);
const user = useFirestore<User>(userDocRef);
export interface User {
  id?: string;
  userType?: UserType;
  createdAt?: Timestamp;
  email?: string;
  displayName?: string;
  firstName?: string;
  lastName?: string;
  initials?: string;
  passwordUpdatedAt?: Timestamp;
  photoUrl?: string;
  phoneE164Format?: string;
  phoneNationalFormat?: string;
  stripeId?: string;
  stripeLink?: string;
  googleTokens?: {
    access_token: string;
    expiry_date: number;
    id_token: string;
    refresh_token: string;
    token_type: string;
  };
}

This solution addresses the immediate problem, but I'm still uncertain about the necessity of having all interface properties set as optional. It feels overly rigid.

If anyone can shed light on this matter, please share your insights in the comments below.

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

Ways to Conceal Information in Angular2

On my website, I have a layout with three tabs. In the third tab, I've implemented an ng-select tag. My goal is to only display the 1st ng-select tag initially, while keeping the other two hidden until the user selects data in the 1st tag. For referen ...

Troubleshooting: Issue with displaying router-view in Laravel Vue

Currently, I am endeavoring to enhance my understanding of Single Page Applications by constructing one with Laravel, Vue, Vue Router, and Vuex. Unfortunately, I have encountered an issue where the router-view is not rendering at all, no matter what troub ...

Using conditional routing for nested routes in VueJS

Is there a way to conditionally redirect a children route? I've experimented with various methods but haven't had any success. Currently, I am using a state from the store as the condition to redirect the children routes. I have exported my stor ...

Adjust the Vue.js background color according to a specified class name

Just starting out with vue.js and exploring the possibilities. I have a scenario where I need to dynamically change the background color based on a class name in vue. Is there a way to achieve this without relying solely on CSS? Ideally, I would like to si ...

Access functions and attributes in separate namespaces using a callback function

Incorporating the chartjs-plugin-annotation, I am faced with the need to trigger an event once a user clicks on an annotation to display a tooltip text. The plugin offers an event handler for the click event that allows me to retrieve the clicked element: ...

Uh-oh, looks like there's a problem resolving '@firebase/webchannel-wrapper'

After upgrading to the latest version of angularfire2, I encountered some issues despite following the installation guide. The error message I'm receiving is: [18:57:50] ionic-app-script task: "build" [18:57:50] Error: ./node_modules/firebase/fires ...

What is the best way to integrate OAuth into a stateless REST API?

Is there a way to utilize OAuth statelessly on a node/express server without breaking the statelessness of my REST api while using Passport for transferring user information through sessions? ...

Having trouble with deploying a Vuejs app from git on Jelastic

This is my first experience with Jelastic and I am attempting to deploy a Vue.js app from Git. After creating a Node.js environment and deploying my Vue.js app, I followed these steps: cd ROOT npm install npm run build I received a successful message th ...

Storing checkbox status in Angular 7 with local storage

I am looking for a way to keep checkboxes checked even after the page is refreshed. My current approach involves storing the checked values in local storage, but I am unsure of how to maintain the checkbox status in angular 7 .html <div *ngFor="let i ...

What is the recommended approach for testing a different branch of a return guard using jest?

My code testing tool, Jest, is indicating that I have only covered 50% of the branches in my return statement test. How can I go about testing the alternate branches? The code snippet below defines a function called getClient. It returns a collection h ...

Error in Vue Vuelidate appearing when form is submitted with empty data property

I have been working on some basic validation for required fields and minimum length. The problem arises when I submit a network request for data insertion, the validation works perfectly fine. However, after the network call, if I try to make my text fie ...

Using AngularJS with CDN: A beginner's guide

If I need to create an app using AngularJS with Cordova in Visual Studio, do I need anything else besides the Google CDN for AngularJS? <!doctype html> <html ng-app> <head> <title>My Angular App</title> <script s ...

Creating a class that utilizes a data source from JavaScript

I am trying to create a data source list using JavaScript in vue.js <div class="{{item.clockIn}}"></div> The value returned by {{item.clockIn}} can be either true or false. .true { content: 'IN'; color: blue; } .true { content: &ap ...

What is the proper syntax for using .focus() with the nextElementSibling method in typing?

As I strive to programmatically shift focus in my form using nextElementSibling, I encounter a challenge with typing variables/constants due to working with Typescript... I have managed to achieve success without typing by implementing the following: myF ...

Utilize an alias to define the SCSS path in an Angular-CLI library project

I am in the process of developing a library project using angular-cli. I have been following the guidelines outlined in the angular documentation. This has resulted in the creation of two main folders: one is located at ./root/src/app, where I can showcase ...

Where is the best place to declare an element variable in Vue so that it can be accessed in any component lifecycle or

I've recently started learning Vue and I'm curious about where to define something like: const qualityDropdown = document.getElementById("qualityDropdown"); In a way that allows me to access it in any lifecycle or method of a component without ...

Creating an asynchronous function that can handle a variable number of arguments and returns the appropriate data type

I'm looking to create a helper function that can wrap an existing async function with a variable number of arguments, allowing me to call it like this: const submit = wrapLoading(async (values: string[]) { // await something with values return tru ...

Guidelines for eliminating a row from an Angular Material table

I am currently working on a shopping cart feature using an Angular Material table. Each row in the table displays a picture, description, and a delete button. However, I'm facing an issue where clicking the delete button does not remove the row from t ...

Transmitting data from Angular to .NET Core for seamless integration

I have been attempting to send an xls or any other file from my angular application to a .NET core controller, but none of my methods seem to work... Below is my component where I call my service upon button click: handleFileInput(file: FileList) { this. ...

Combining types: unable to utilize the second optional type within a for loop

I am facing an issue while looping through an array due to the union type. I am wondering what I have overlooked in the code below that is causing Visual Studio Code to not recognize the second optional type for that specific array. class Menu { // name ...