What steps can be taken to avoid repetitive user creation in Firebase?

While developing an event app using the Ionic 4 framework with Firebase as the back-end, I ran into an issue with user creation on the Cloud Firestore database. Every time a user logs in using Google or Facebook, Firebase creates a new entry in the database even if the user is the same. I have tried to implement a check to see if the user_id already exists in the database, but there seems to be an issue in my code. How can I troubleshoot and correct this problem so that my code accurately verifies if the current user already exists in the database?

The existing code has the check for user existence in the Cloud Firestore database within the login component. I also attempted to integrate the check directly into the createUser() function in my user service, but the behavior remained unchanged.

Here is the function in my login component:

googleLogin() {
    if (this.authService.googleLogin()) {
    this.authService.getAuthState().subscribe(user => {
        if (user) {
          console.log("Logged In ", user.email);
          this.userId = user.uid;
          this.user.name = user.displayName;

          this.afs.firestore.doc('user/' + user.uid).get()
          .then(docSnapshot => {
            if (docSnapshot.exists) {
              console.log("user already exists");
            } else {
              this.userservice.createUser(this.user);
            }
          });
        } else {
          console.log("Not Logged In");
          this.userId = undefined;
        }
      }
    );

Here is the createUser function in my user service:

createUser(user: any): Promise<any> {
      return this.afs.collection("user").add({
        blockPushMessages: user.blockPushMessages,
        email: user.email,
        isAnonymous: user.isAnonymous,
        name: user.name,
        partyLevel: user.partyLevel,
        aliasName: user.aliasName,
        dateOfBirth: user.dateOfBirth,
        gender: user.gender,
        homeTown: user.homeTown,
        personImage_id: user.personImage_id,
        registrationDate: user.registrationDate,
        relationshipStatus: user.relationshipStatus,
        school: user.school
      });
  }

And here are the google login functions in my auth service:

googleLogin() {
    if (this.platform.is("cordova")) {
      this.nativeGoogleLogin();
    } else {
      this.webGoogleLogin();
    }
    return true;
  }

async nativeGoogleLogin(): Promise<firebase.User> {
    try {
      const gplusUser = await this.gplus.login({
        webClientId:
          "**********",
        offline: true,
        scopes: "profile email"
       });
       return await this.afAuth.auth.signInWithCredential(
        firebase.auth.GoogleAuthProvider.credential(gplusUser.idToken)
      );
    } catch (err) {
      console.log(err);
    }
  }

 async webGoogleLogin(): Promise<void> {
    try {
      const provider = new firebase.auth.GoogleAuthProvider();
      const credential = await this.afAuth.auth.signInWithPopup(provider);
    } catch (err) {
      console.log(err);
    }
  }

My expectation is that the code should verify if the current user already exists in the Cloud Firestore database. However, the current behavior is that the check is ignored, and a new user is created in the database even if the user is the same. If anyone can identify the issue with my code, I would greatly appreciate your insight!

Answer №1

It appears that you are checking the uid; could it be possible that the uid corresponds to the user id in your backend system?

Answer №2

Instead of comparing the uid to a randomly generated document ID in my database, I made changes to the code. I assigned an internal_id to my user object and used the uid to create the user document in the database. Here is the updated solution:

Snippet from my user service:

createUser(user: any): Promise<any> {
      return this.afs.collection("user").doc(user.internal_id).set({
        internal_id: user.internal_id,
        blockPushMessages: user.blockPushMessages,
        email: user.email,
        isAnonymous: user.isAnonymous,
        name: user.name,
        partyLevel: user.partyLevel,
        aliasName: user.aliasName,
        dateOfBirth: user.dateOfBirth,
        gender: user.gender,
        homeTown: user.homeTown,
        personImage_id: user.personImage_id,
        registrationDate: user.registrationDate,
        relationshipStatus: user.relationshipStatus,
        school: user.school
      });
  }

Snippet from my login component:

googleLogin() {
    if (this.authService.googleLogin()) {
    this.authService.getAuthState().subscribe(user => {
        if (user) {
          // User is signed in.
          console.log("Logged In ", user.email);
          this.user.internal_id = user.uid;
          this.internal_id = user.uid;
          this.user.name = user.displayName;

          this.afs.firestore.doc('user/' + this.internal_id).get()
          .then(docSnapshot => {
            if (docSnapshot.exists) {
              console.log("user already exists");
            } else {
              this.userservice.createUser(this.user);
            }
          });
        } else {
          console.log("Not Logged In");
          this.userId = undefined;
        }
      }
    );

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

Connecting HTML to an AngularFirestore collection using snapshotChanges

In my mobile app, I am using AngularFirestore2v5/rxjs to connect a hybrid Ionicv3/Angularv4 app to a Firestore collection. While binding UI with AngularFirestore.valueChanges works fine, switching to snapshotChanges for retrieving the id is causing some is ...

Currently, I am working on developing a to-do task manager using Angular 2. One of the tasks I am tackling involves updating the value

I'm facing an issue with managing to-do tasks. I would like to update the value of an option in a select dropdown when the (change) event is triggered. There are 2 components: //app.component.ts //array object this.dataArr[this.counter] = {id: this ...

How to Customize Checkbox Appearance in PrimeNG

Seeking to customize the visual appearance of the label for a PrimeNG checkbox element: <div class="ui-g-7"> <p-checkbox name="group1" value="Los Angeles" label="Los Angeles" [(ngModel)]="selectedCities" inputId="la"> </p-checkbox&g ...

Warning in TypeScript: TS7017 - The index signature of the object type is implictly assigned as type "any"

An alert for TypeScript warning is popping up with the message - Index signature of object type implicitly has any type The warning is triggered by the following code block: Object.keys(events).forEach(function (k: string) { const ev: ISumanEvent ...

Angular: The component is missing a provider, and the [multiple Angular HTML elements] are unrecognized

I have encountered a series of unit test failures that are puzzling me: 'mat-card' is not recognized as an element (used in the 'ChatCardComponent' component template): 'app-card' is not recognized as an element (used in the ...

How to Maintain Default Styling in Next.js with Material UI When Disabling Accordion Feature

I am currently working on a project using Next.js and incorporating Material UI for the user interface elements. One particular challenge I am facing is with an Accordion component that needs to be disabled under specific conditions, but still appear witho ...

The toggle-input component I implemented in React is not providing the desired level of accessibility

Having an accessibility issue with a toggle input while using VoiceOver on a Mac. The problem is that when I turn the toggle off, VoiceOver says it's on, and vice versa. How can I fix this so that VoiceOver accurately states whether the toggle is on o ...

Transitioning from Webpack to Vite: Resolving Path Alias and Ensuring Proper Imports

Recently, I decided to transition my project from Webpack to Vite with "vite": "^4.3.9",. However, upon running npm start, I encountered the following error: Error: The dependencies imported could not be resolved: In my React Typesc ...

Handle and manage errors within the controller in Express.js to prevent the further execution of asynchronous functions

Consider a scenario where there is an API endpoint /register, designed to register new users in an application. The function utilized is asynchronous, as an attempt is made to incorporate an asynchronous process within an AuthController when performing pas ...

Encountered a hiccup while utilizing react-jsonschema-form alongside Material in a TypeScript project

I’m currently working with the react-jsonschema-form library in my project, using React, Material UI, and Typescript. Specifically, I’m utilizing the Material UI themed form called MuiForm5. However, I’m encountering a compilation error when trying t ...

Managing errors with the RxJS retry operator

I'm facing an issue with my RxJS code where I need to continuously retry a data request upon failure while also handling the error. Currently, I am using the retry operator for this purpose. However, when attempting to subscribe to the retry operator ...

Container that displays vertical scroll while permitting floating overflows

Is there a way to set up a container so that when the window size is too small, it displays a scroll bar to view all elements that don't fit in one go? At the same time, can the child containing floating elements be allowed to extend beyond the bounda ...

In TypeScript version 2.4.1, the fontWeight property encounters an error where a value of type 'number' cannot be assigned to the types of '"inherit", 400'

When attempting to set the fontWeight property in TypeScript, I encounter the following error: Types of property 'test' are incompatible. Type '{ fontWeight: number; }' is not assignable to type 'Partial<CSSProperties>&a ...

Unleash the power of a module by exposing it to the global Window object using the dynamic

In my development process, I am utilizing webpack to bundle and manage my TypeScript modules. However, I am facing a challenge where I need certain modules or chunks to be accessible externally. Can anyone guide me on how to achieve this? Additional conte ...

NG8003 error: ExportAs 'ngForm' directive not found in the system

I encountered an issue with my first Angular 11 project: No directive found with exportAs 'ngForm'. Despite importing FormsModule and ReactiveFormsModule in app.module.ts, the error persists. Here is the code snippet: This is from product.compon ...

The connection to Firebase is being refused when attempting to use the http.post method in Ionic

In my Ionic 3 Angular app deployed on Firebase static hosting, the problematic section of code appears as follows: var data = {"message" : time, "user_id" : user}; return new Promise((resolve, reject) => { ...

What steps are involved in setting up a sorting feature?

In order to utilize the array.sort() function, a number-returning function must be specified. Typically, it would look something like this: myArray.sort((item1, item2) => a < b); However, I am aiming for a different structure: myArray.sort(by(obj ...

Having difficulty importing the WebRTCAdaptor from the antmedia package stored in the node modules directory into an Angular Typescript file

An error is appearing indicating that: There seems to be a problem finding a declaration file for the module '@antmedia/webrtc_adaptor/js/webrtc_adaptor.js'. The file 'D:/web/node_modules/@antmedia/webrtc_adaptor/js/webrtc_adaptor.js' ...

Eliminate apostrophes in a string by using regular expressions

Can someone help me with this word What is The Answer? I need to eliminate the space and apostrophe '. To remove spaces, should I use this method: data.text.replace(/ +/g, ""). But how can I remove the apostrophe? ...

Having T extend Record<string, any>, the keyof T does not return 'string' as a type

My goal is to achieve the following: type UserDataProps<FieldName extends keyof DataShape, DataShape extends Record<string, any>> = { id: string; value: DataShape[FieldName]; } const userDataBuilder = <FieldName extends keyof DataShape, ...