Make a chat app with Svelte + Firebase v9 Finale

Make a chat app with Svelte + Firebase v9 Finale

First of all, sorry because I haven't been blogging for a while😅. Let's go ✈!

Now we just have to implement the adding. First, let's make an input and a button in App.svelte.

Some elements

<div class="inp">
  <input type="text" bind:value={inp} />
  <button on:click={add}>send</button>
</div>

If you are confused about what bind is, check this out: svelte.dev/tutorial/text-inputs.

Let's not forget to declare the variable inp:

let inp;

Adding Data to database

Now, let's make a function for adding data to the Database:

const add = () => {
    addDoc(col, {
      purrson: inp ? inp : "",
      message: auth.currentUser ? auth.currentUser.displayName : "Anonymous",
      time: Date.now(),
    });
    inp = "";
    console.log(auth);
  };

Here, we are adding data to the database. We are taking inp as the message, and taking the name of the user if he is signed in, else we are taking the name as Anonymous.

Sorting data

For sorting data, we can use the things Firebase provides, but I'll just use Array.sort 😏.

Your onSnapshot code should look like this:

onSnapshot(col, (snapshot) => {
    let arr = [];
    snapshot.docs.forEach((doc) => {
      arr.push({ ...doc.data(), id: doc.id });
    });
    data = arr.sort((a, b) => (a.time > b.time ? 1 : -1));
  });

Some CSS

Now it should work! Let's do some very basic styling in App.svelte...

<style>
  @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@300;600&display=swap");
  h1 {
    font-family: Poppins, sans-serif;
    font-weight: 600;
  }

  p {
    font-family: Poppins, sans-serif;
    font-weight: 400;
  }
  h2 {
    font-family: Poppins, sans-serif;
    font-weight: 600;
  }

  .cont {
    background-color: rgb(255, 193, 193);
    border-radius: 20px;
  }
  input {
    width: 80%;
  }
  .inp {
    position: fixed;
    bottom: 0;
    width: 100%;
  }
</style>

Well, you should get something good... here's all the source code!

All the code

firebase.js

// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
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,
};

// Initialize Firebase
initializeApp(firebaseConfig);

import {
  getAuth,
  signInWithPopup,
  signOut,
  GoogleAuthProvider,
} from "firebase/auth";

const auth = getAuth();
const provider = new GoogleAuthProvider();
const si = () => {
  signInWithPopup(auth, provider)
    .then((result) => {
      // This gives you a Google Access Token. You can use it to access the Google API.
      const credential = GoogleAuthProvider.credentialFromResult(result);
      const token = credential.accessToken;
      // The signed-in user info.
      const user = result.user;
      console.log(user);
      // ...
    })
    .catch((error) => {
      // Handle Errors here.
      const errorCode = error.code;
      const errorMessage = error.message;
      // The email of the user's account used.
      const email = error.email;
      // The AuthCredential type that was used.
      const credential = GoogleAuthProvider.credentialFromError(error);
      // ...
    });
};

const so = () => {
  signOut(auth)
    .then(() => {
      alert("hello");
    })
    .catch((error) => {
      // An error happened.
    });
};
import {
  addDoc,
  collection,
  getFirestore,
  onSnapshot,
} from "firebase/firestore";

const db = getFirestore();
const col = collection(db, "messages");

export { si, so, col, addDoc, auth, onSnapshot };

App.svelte

<script>
  import { si, so, col, addDoc, auth, onSnapshot } from "./firebase";

  let data = [];
  let inp;
  console.log(col);
  onSnapshot(col, (snapshot) => {
    let arr = [];
    snapshot.docs.forEach((doc) => {
      arr.push({ ...doc.data(), id: doc.id });
    });
    data = arr.sort((a, b) => (a.time > b.time ? 1 : -1));
  });

  const add = () => {
    addDoc(col, {
      message: inp ? inp : "",
      purrson: auth.currentUser ? auth.currentUser.displayName : "Anonymous",
      time: Date.now(),
    });
    inp = "";
    console.log(auth);
  };
</script>

<button on:click={si}>login</button>
<button on:click={so}>logout</button>

{#each data as { message, purrson, time }}
  <div class="cont">
    <h1>{purrson}</h1>
    <p>{new Date(time).toUTCString()}</p>
    <h2>{message}</h2>
  </div>
{/each}

<div class="inp">
  <input type="text" bind:value={inp} />
  <button on:click={add}>send</button>
</div>

<style>
  @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@300;600&display=swap");
  h1 {
    font-family: Poppins, sans-serif;
    font-weight: 600;
  }

  p {
    font-family: Poppins, sans-serif;
    font-weight: 400;
  }
  h2 {
    font-family: Poppins, sans-serif;
    font-weight: 600;
  }

  .cont {
    background-color: rgb(255, 193, 193);
    border-radius: 20px;
  }
  input {
    width: 80%;
  }
  .inp {
    position: fixed;
    bottom: 0;
    width: 100%;
  }
</style>

Did you find this article valuable?

Support Raghav Singh Gulia by becoming a sponsor. Any amount is appreciated!