Building a Streak System in React with Firebase

Thumbnail

Written by: developervsandhu

Technology and Gadgets

Building a Streak System in React with Firebase

Introduction

Streak systems are popular features in many apps to keep users engaged. Whether it's a language-learning app like Duolingo or a productivity tool, tracking how often users return can boost retention. In this blog, we'll walk through building a streak-like system using React and Firebase. This system will track users' daily activities and reward them for consecutive days of participation.

Prerequisites

To follow along, you should have:

  • Basic Knowledge of React
  • A Firebase Project set up (Authentication and Firestore)

Firebase Setup

If you haven't already, start by setting up Firebase in your project. Run the following command to install the Firebase SDK:

npm install firebase	

Next, initialize fierbase in your project by adding fierbase config

// firebase.js
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getAuth } from "firebase/auth";

const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID",
};

const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
const auth = getAuth(app);

export { db, auth };

Step 2: Authentication

For simplicity, we'll use Firebase Authentication to track which user is logged in. You can implement email/password authentication or Google sign-in for your app. Firebase makes it easy to authenticate users.

import { onAuthStateChanged } from "firebase/auth";
import { auth } from "./firebase"; // Firebase config

useEffect(() => {
  onAuthStateChanged(auth, (user) => {
    if (user) {
      console.log("User logged in:", user);
    } else {
      console.log("No user logged in");
    }
  });
}, []);

Step 3: Setup Firestore

Our streak system will store each user’s streak count and the last day they were active in Firestore. The basic structure for each user will look like this:

users: {
  userId: {
    streakCount: 3,            // Number of consecutive days
    lastActive: Timestamp,      // Last day of activity
  }
}

Step 4: implementing Streak Logic

Now, let's implement the logic to track streaks. We'll check if the user was active yesterday and update their streak accordingly. If they missed a day, the streak will reset.

import { doc, getDoc, setDoc, updateDoc, serverTimestamp } from "firebase/firestore";
import { db } from "./firebase"; // Firebase config
import { useEffect, useState } from "react";
import { Timestamp } from "firebase/firestore";

function StreakSystem() {
  const [user, setUser] = useState(null);
  const [streak, setStreak] = useState(0);

  useEffect(() => {
    // Assuming the user is already logged in
    const checkStreak = async (userId) => {
      const userRef = doc(db, "users", userId);
      const userSnap = await getDoc(userRef);
      
      const today = new Date();
      today.setHours(0, 0, 0, 0); // Normalize time
      
      if (userSnap.exists()) {
        const { lastActive, streakCount } = userSnap.data();
        const lastActiveDate = lastActive.toDate();
        lastActiveDate.setHours(0, 0, 0, 0);

        const diffInDays = (today - lastActiveDate) / (1000 * 3600 * 24);
        
        if (diffInDays === 1) {
          // Continue the streak
          await updateDoc(userRef, { streakCount: streakCount + 1, lastActive: serverTimestamp() });
          setStreak(streakCount + 1);
        } else if (diffInDays > 1) {
          // Reset the streak
          await updateDoc(userRef, { streakCount: 1, lastActive: serverTimestamp() });
          setStreak(1);
        } else {
          // Already active today
          setStreak(streakCount);
        }
      } else {
        // First time logging activity
        await setDoc(userRef, { streakCount: 1, lastActive: serverTimestamp() });
        setStreak(1);
      }
    };

    // Call checkStreak for the current user
    if (user) {
      checkStreak(user.uid);
    }
  }, [user]);

  return (
    <div>
      <h1>Your current streak: {streak} days</h1>
    </div>
  );
}

export default StreakSystem;

Step 5: Display the Streak

In this component, the streak value will be dynamically updated each time a user logs in. You can style this part of the UI to show the user how many consecutive days they've been active.

return (
  <div>
    {user ? (
      <div>
        <h1>Welcome back, {user.email}</h1>
        <p>Your current streak: {streak} days</p>
      </div>
    ) : (
      <p>Please log in to see your streak.</p>
    )}
  </div>
);

Step 6: Additional Features (optional)

Now that the basic system is in place, you can build upon it by adding features like:

-Rewards for milestones: Give badges or points for maintaining long streaks.

-Reminder notifications: Send push notifications or emails to remind users to log in before their streak resets.

-Detailed activity tracking: Instead of just logging activity, you can track specific actions like completing tasks or making posts.

Conclusion

By following this tutorial, you've built a functional streak system in React using Firebase. This is a simple but powerful feature that encourages user engagement through daily activity. Firebase’s real-time database and authentication make it easy to track user-specific data, and React makes it simple to display that information.

Login To Add Comment

No comments yet.