Building a custom user authentication system using Angular, Firebase, and Google authentication

Recently, I came across this video (in code), and implemented my Auth Service based on the example provided. However, my User Interface structure is slightly different:

interface User {
  uid: string;
  email: string;
  photoURL: string;
  displayName: string;
  status?: string;
  karma?: number;
}

I intend for 'status' to represent typical online/busy/away statuses, while 'karma' will be a numerical value that allows users to rate each other.
The updateUserData function, responsible for saving the user's data in Firestore, is as follows:

private updateUserData({ uid, email, displayName, photoURL }) {
    const userRef: AngularFirestoreDocument<User> = this.afs.doc(
      `users/${uid}`
    );

    const data: User = {
      uid,
      email,
      displayName,
      photoURL,
      status: 'online',
      karma: 0
    };

    return userRef.set(data, { merge: true });
  }

My dilemma lies in the fact that each time a user signs in, the 'karma' value gets reset to 0.
How can I ensure that the 'karma' value is retained if the user already exists in the Firestore database?

I attempted to use a boolean variable named "amINew" in the constructor, with the idea that it would be set to false if the user data is found in Firestore, and true if not.

amInew: boolean;

  constructor(
    private afAuth: AngularFireAuth,
    private afs: AngularFirestore,
    private router: Router,
    public ngZone: NgZone
  ) {
    this.user$ = this.afAuth.authState.pipe(
      switchMap(user => {
        if (user) {
          this.amInew = false;
          return this.afs.doc<User>(`users/${user.uid}`).valueChanges();
        } else {
          this.amInew = true;
          return of(null);
        }
      })
    );
  }

However, I encountered an issue where the "amINew" variable always remained true, even when testing with a new user registration.

What should be my approach to solve this issue effectively?

Answer №1

To update karma, consider the following method:

const userDetails: Profile = {
  userId,
  email,
  displayName,
  profilePic,
  status: 'active',
  karma: existingKarma + 1;
};

You can use the karma value to determine if it's the user's first sign-in.

When registering, initialize karma to 0

user.karma = 0;

Then, for login:

if (user.karma === 0) {
    // Indicates first sign-in
    user.karma = 1;
}

Answer №2

Implementing different functions for updating a user's information based on whether they are signing in for the first time or just logging in can be a smart approach. For new sign-ups, it makes sense to initialize certain fields such as karma to 0, whereas for returning users, you may only need to update specific fields using the update function. It seems essential to update the status field at least after a regular login, rather than a sign-up:

private updateStatus(uid: string) {
  const userRef: AngularFirestoreDocument<User> = this.afs.doc(
    `users/${uid}`
  );
  return userRef.update({status: 'online'});
}

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

NestJS's "Exclude" decorator in class-transformer does not exclude the property as expected

I attempted to exclude a specific property within an entity in NestJS, but it appears that the exclusion is not working as expected. When I make a request, the property is still being included. Code: // src/tasks/task.entity.ts import { Exclude } from &ap ...

Changing a date format in typescript: Here is how you can easily convert a date from one

Using React with Typescript: I am currently working with a date picker from material-ui version 5. The date picker requires the date value to be in the format "yyyy-MM-dd". However, the API returns a Date object in the format "2022-01-12T00:00:00.000+00:0 ...

Challenges surrounding asynchronous functionality in React hooks

I've been facing some issues with this code and have resorted to debugging it using console.log(). However, the results I'm getting are not making any sense. Can someone help me identify what's wrong with this code? I noticed that my console ...

Having trouble retrieving the URL from the router in Angular 2?

Whenever I try to access the URL using console.log(_router.url), all it returns is a / (forward slash). Here is the code snippet in question: constructor( private el: ElementRef, private _auth:AuthenticationService, @Inject(AppStore) private ...

Having trouble capturing emitted events from a child component in Angular 2+?

I have a question as a beginner. I'm trying to send a message from the child component to the parent component but for some reason, it's not working. app.component.html <app-cart-component> [items]="rootItems" (outputItems)=&quo ...

There seems to be an issue with the functionality of Angular Material on iOS devices

I recently developed a website using Angular and Angular Material. While the site functions properly on Windows and Android across all browsers, I encountered an issue with iOS devices running Safari. Some elements on the page do not display correctly on i ...

Urgent dependency alert: calling for a necessity (sequelize) in next.js is a vital element

I'm encountering a challenge with integrating sequelize into my Next.js 13 project to connect my API routes with the database. I keep receiving errors that say "Critical dependency: the request of a dependency is an expression." import * as pg from &a ...

In a standalone script, the error message "ReferenceError: exports is not defined in ES module scope" is encountered

When I execute the script using npx ts-node -i --esm --skipProject -T .\seed.ts import { readdir, readFile } from "node:fs/promises" async function readFeedsFromFiles() { const data = await readdir("./seedData/feeds", { ...

Tips on transforming Angular 2/4 Reactive Forms custom validation Promise code into Observable design?

After a delay of 1500ms, this snippet for custom validation in reactive forms adds emailIsTaken: true to the errors object of the emailAddress formControl when the user inputs [email protected]. https://i.stack.imgur.com/4oZ6w.png takenEmailAddress( ...

Retrieving the necessary data from my object to perform a sum calculation in angular

Having trouble retrieving an attribute from an array in my code. In my .ts file, I am fetching data from my backend endpoint like this: export class PostFeedComponent implements OnInit { data: any = {}; constructor(private http: HttpClient) { t ...

Having trouble getting the styles property to work in the component metadata in Angular 2?

Exploring Angular 2 and working on a demo app where I'm trying to apply the styles property within the component metadata to customize all labels in contact.component.html. I attempted to implement styles: ['label { font-weight: bold;color:red } ...

Having trouble grasping this concept in Typescript? Simply use `{onNext}` to call `this._subscribe` method

After reading an article about observables, I came across some code that puzzled me. I am struggling to comprehend the following lines -> return this._subscribe({ onNext: onNext, onError: onError || (() => {}), ...

Tips for transforming your angular application into a custom npm package or library

Recently, I've been working on an Angular application that fetches photos and videos from a server and displays them as a slide one at a time. Now, I'm faced with the task of integrating this functionality into another app. Is there a method to t ...

Is there a solution to resolve the Firestore issue stating: "FieldPath.documentId is not a recognized function"?

In my function, I am retrieving data from two collections in Firestore: Media and Users. Inside the Users collection, there is a subcollection containing a list of all the user's movies. The Media collection includes details about each movie. My goal ...

Is it possible to utilize Angular translate to support multiple languages for individual components or modules?

Utilizing ngx-translate to switch the language of my application has proven to be quite challenging. My application consists of different languages specifically for testing purposes and is divided into separate modules with lazy loading functionality. As ...

Automatically assign the creation date and modification date to an entity in jhipster

I am currently working on automatically setting the creation date and date of the last change for an entity in JHipster, utilizing a MySQL Database. Below is my Java code snippet for the entity: @GeneratedValue(strategy = GenerationType.AUTO) @Column(nam ...

Encountering an error message stating "Buffer is not defined" while working with gray-matter

Encountering an issue when trying to utilize gray-matter in Angular 9, the error message displayed is: ReferenceError: Buffer is not defined at Object.push../node_modules/gray-matter/lib/utils.js.exports.toBuffer (utils.js:32) at push../node_modul ...

The type inference in TypeScript sometimes struggles to accurately determine the type of an iterable

Struggling to get TypeScript to correctly infer the underlying iterable type for the function spread. The purpose of this function is to take an iterable of iterable types, infer the type of the underlying iterable, and return a new iterable with that infe ...

What steps can I take to troubleshoot and repair my accordion feature within an Angular project?

As a newcomer to Angular, I recently attempted to create an accordion component but encountered unexpected behavior. Here is the HTML code for my attempt: <div class="faq-item-container"> <h1 class="mt-1 mb-5"><strong>Frequently A ...

Issues arise when Typescript fails to convert an image URL into a base64 encoded string

My current challenge involves converting an image to base 64 format using its URL. This is the method I am currently using: convertToBase64(img) { var canvas = document.createElement("canvas"); canvas.width = img.width; canvas.height = img.he ...