2. AppWrite
in my project i have creaated a seperate folder named appwrite and all the appwrite configs are in this folder
now first i created auth.js file where users createaccount,login,logout will happen
//note for future :- upgrade if i want to change the baas change this auth file class data but keep the same params
import conf from '../conf.js';
import { Client, Account,ID } from 'appwrite';
export class AuthService {
client = new Client();
account; //got an error earlier as i didnt defined account outside the constructor and used it directly inside
//so i am using this empty declation here
constructor() {
this.client
.setEndpoint(conf.appwriteUrl)
.setProject(conf.appwrtieProjectId);
this.account = new Account(this.client);
}
async createAccount({email, password, name}) {
//used try catch coz got appwrite stuck previously and returned null not found
try{
const userAccount = await this.account.create(
ID.unique(), // Generate a unique user iD
email,
password,
name
);
if(userAccount){
return this.login({email, password}); // Automatically will log in after account creation
} else{
return userAccount
}
}
catch (error) {
console.error('Error creating account:', error);
}
}
async login({email, password}) {
try{
return await this.account.createEmailSession(email, password);
}catch (error) {
console.error('Error logging in:', error);
}
}
async getCurrentUser() {
try{
await this.account.get(); // This will throw an error if the user is not logged in
}catch (error) {
console.error('Error fetching current user:', error);
}
return null; // If the user is not logged in, return null and webpage will not reload
}
async logout() {
try{
await this.account.deleteSessions(); // Deletes all current session on every browser for logging out from current session use deleteSession not deleteSessions
return true; // Return true if logout was successful
}catch(error){
console.error('Error logging out:', error);
}
}
}
const authService = new AuthService();
export default authService;
AuthService Class Explanation
This file defines a class-based service for handling authentication using Appwrite. The structure is created with flexibility in mind so that switching to another Backend-as-a-Service (BaaS) later (like Firebase or Supabase) requires changes only in this file, not across the entire codebase.
1. Imports
import conf from '../conf.js';
import { Client, Account, ID } from 'appwrite';
conf: Contains Appwrite configuration values like URL, Project ID, etc.Client: The main class to initialize and connect to Appwrite services.Account: Used to perform all account-related operations (sign-up, login, get user, logout).ID: Utility to generate unique user IDs.
2. Class Structure
export class AuthService {
client = new Client();
account;
constructor() {
this.client
.setEndpoint(conf.appwriteUrl)
.setProject(conf.appwrtieProjectId);
this.account = new Account(this.client);
}
}
Explanation:
client = new Client()is a class field that initializes the Appwrite client.account;is a forward declaration to prevent runtime errors if used before being initialized.- The
constructor()sets the API endpoint and project ID using environment variables and then initializes theaccountobject with the client.
3. createAccount Method
async createAccount({email, password, name}) {
try {
const userAccount = await this.account.create(
ID.unique(),
email,
password,
name
);
if (userAccount) {
return this.login({email, password});
} else {
return userAccount;
}
} catch (error) {
console.error('Error creating account:', error);
}
}
- Registers a new user.
- Uses
ID.unique()to auto-generate a unique user ID. - If successful, immediately logs in the user by calling the
login()method.
4. login Method
async login({email, password}) {
try {
return await this.account.createEmailSession(email, password);
} catch (error) {
console.error('Error logging in:', error);
}
}
- Authenticates a user using their email and password.
- Returns the session if login is successful.
5. getCurrentUser Method
async getCurrentUser() {
try {
await this.account.get();
} catch (error) {
console.error('Error fetching current user:', error);
}
return null;
}
- Retrieves the currently logged-in user's details.
- If the user is not logged in, it catches the error and returns
null.
6. logout Method
async logout() {
try {
await this.account.deleteSessions();
return true;
} catch (error) {
console.error('Error logging out:', error);
}
}
- Logs out the user by deleting all active sessions.
- Returns
trueon successful logout.
7. Exporting the Service
const authService = new AuthService();
export default authService;
- Creates a single instance of the
AuthServiceclass to be reused throughout the project.
Design Note
This design pattern allows you to:
- Centralize all authentication logic in one place.
- Easily maintain and extend authentication features.
- Replace the backend service later by modifying only this class while keeping method signatures and usage consistent.