Svelte, Snapshot & Cannot destructure property error

I am creating a Svelte application using Firebase Database and am trying to convert a simple Firebase call to use a Query Snapshot, rather than a Get, so that I can instantly see changes on screen if the database changes.

I have some working code but it is currently not updating as I need it to and when I use the Query Snapshot code it stops working almost completely. For the purposes of this – I am simply trying to get a list of Users from the database and display them on a page, which updates if any new users are added or details are changed without the need to refresh. I will list both the working and non-working code below:

Working Code

allUsersStore.JS

import { fetchUsers } from "@api/allUsers";
import { onMount } from "svelte";
import { writable } from "svelte/store"

export function allUsersStore() {

    const users = writable([]);
    const loading = writable(false);
 

   
    onMount(loadUsers);
    
    async function loadUsers() {
    loading.set(true);
try{

   const {users: theUsers} = await fetchUsers();
   
   
   
//  console.log(theUsers)

  users.set(theUsers);



} catch(e) {
console.log("ERROR!" + e.message);
}

finally {
loading.set(false);
}



       
    }
    
    
    
 
    
    return {
    //  assignedUser: { subscribe: assignedUser.subscribe },
    users: { subscribe: users.subscribe },
    loading: { subscribe: loading.subscribe },
       // users
    
    }
    
    }

allUsers.js

import { db } from "@db/index";
import { getCountFromServer, Timestamp, doc, collection, getDocs, query, addDoc, orderBy, getDoc, where, setDoc, onSnapshot, updateDoc, deleteDoc, arrayUnion, arrayRemove } from "firebase/firestore";
async function fetchUsers() {

 const q = query(collection(db, "userData"), orderBy('fullName', 'asc'));
 const qSnapshot = await getDocs(q);
 
 const users = qSnapshot.docs.map(doc => {
     const user = doc.data();
    
     return {...user, id: doc.id}
 });


 return {users};
 
 
 }

+page.svelte

<script>
import { allUsersStore } from "@stores/allUsersStore";
const { users, loading} = allUsersStore();
</script>

{#each $users as user (user.id)}
<h2>{user.fullName} </h2>
{/each}

This code works fine to produce a list of Usernames but, as I mentioned above, it will not update if a change to the database is made. As I come from an IOS background I know about Query Snapshots so I tried to implement that solution. All I changed was the call on the allUsers.js page as below:

async function fetchUsers() {

  const q = query(collection(db, "userData"), orderBy('fullName', 'asc'));
  const unsubscribe = onSnapshot(q, (querySnapshot) => {
    const users = [];
    querySnapshot.forEach((doc) => {
        users.push(doc.data());
    });

    
  for (const x of $users) {

console.log(x.fullName)

}



return {users};

  });



}

The console.log is showing the list of users names and I can see this list updating when I trigger a change in the database, however I am now getting an error from the try/catch block on allUsersStore.JS and no list is produced on my +page.svelte. The error is:

Cannot destructure property ‘users’ of ‘(intermediate value)’ as it is undefined

Could some kind person please explain to me what I am doing wrong and if there is a better practice for what I am trying to achieve please?

Thanks in advance 🙂