skip to Main Content

I’m trying to create a user profile edit page where once you have logged in you are routed to this page and then the index returns your unique profile and not everyones profiles but I keep getting this error Uncaught (in promise) TypeError: Cannot read properties of null (reading ‘uid’). I’ve looked up some of the reasons it could be and the user is logged in and i’m not using asynchronous code some I have no idea what the problem is I’m not sure if the uid isn’t getting through before the function runs or what it could be? Here is my vue.js script code on the page where it should display the profiles.

<script>

import getCollection from '../Composables/getCollection';
import getUser from '../Composables/getUser';
import getPremium from "../Composables/getPremium.js";

const {Premium, error, load} = getPremium();
load();





export default{
   
 
    
  setup() {
    const { user } = getUser()
    const { documents: Profile } = getCollection(
      'Premium', 
      ['userId', '==', user.value.uid]
    )
    console.log(Profile)

    return { Profile }
  }
}


</script>


<template>
<br><br>
<div v-if="error">{{ error }}</div>

<div v-if="Profile" class="Profile">
  <p class="text-5xl text-red-700 font-serif">Your Profile Statistics</p>
<div v-for =" Premium in Premium" :key="Premium.id">
<p class="text-5xl text-red-700 font-serif">Your Profile Statistics</p>
<p class="text-5xl text-red-700 font-serif">{{ Premium.name }}</p>
<br><br>
</template>

Here is where I am getUser.js page.

import { ref } from 'vue'
import { projectAuth } from '../firebase/config'

// refs
const user = ref(projectAuth.currentUser)

// auth changes
projectAuth.onAuthStateChanged(_user => {
  console.log('User state change. Current user is:', _user)
  user.value = _user
});

const getUser = () => {
  return { user } 
}

export default getUser

And this is my getCollection.js page.

import { ref, watchEffect } from 'vue'
import { projectFirestore } from '../firebase/config'

const getCollection = (collection, query) => {

  const documents = ref(null)
  const error = ref(null)

  // register the firestore collection reference
  let collectionRef = projectFirestore.collection(collection)
    .orderBy('createdAt')

  if (query) {
    collectionRef = collectionRef.where(...query)
  }

  const unsub = collectionRef.onSnapshot(snap => {
    let results = []
    snap.docs.forEach(doc => {
      // must wait for the server to create the timestamp & send it back
      doc.data().createdAt && results.push({...doc.data(), id: doc.id})
    });
    
    // update values
    documents.value = results
    error.value = null
  }, err => {
    console.log(err.message)
    documents.value = null
    error.value = 'could not fetch the data'
  })

  watchEffect((onInvalidate) => {
    onInvalidate(() => unsub());
  });

  return { error, documents }
}

export default getCollection

As I said neither contain an asynchronous function, the user is logged in it shows up in the console and I’ve been trying to figure out what the problem could be i’ve looked at examples but can’t see any difference between them and mine, I’ve tried having it as a computed function too but that doesn’t work either any help would be greatly appreciated, thanks.

2

Answers


  1. Chosen as BEST ANSWER

    I had to have profile set as premium like this

    <script>
    
    import getCollection from '../Composables/getCollection';
    import getUser from '../Composables/getUser';
    import getPremium from "../Composables/getPremium.js";
    
    const {Premium, error, load} = getPremium();
    load();
    
    
    
    
    
    export default{
       
     
        
      setup() {
        const { user } = getUser()
        const { documents: Premium } = getCollection(
          'Premium', 
          ['userId', '==', user.value.uid]
        )
        console.log(Premium)
    
        return { Premium }
      }
    }
    
    
    </script>
    
    
    <template>
    <br><br>
    <div v-if="error">{{ error }}</div>
    
    <div v-if="Premium" class="Profile">
      <p class="text-5xl text-red-700 font-serif">Your Profile Statistics</p>
    <div v-for =" Premium in Premium" :key="Premium.id">
    <p class="text-5xl text-red-700 font-serif">Your Profile Statistics</p>
    <p class="text-5xl text-red-700 font-serif">{{ Premium.name }}</p>
    <br><br>
    </template>
    

    Once I did this it was fixed.


  2. Looking at your it is probably the getUser function, which is asynchronous. Although is it not clear where this function is coming from in the code you provided. But it looks like that is returning a promise, you should await for. You can use promise chaining for that, like:

    setup() {
        let Profile = null;
    
        getUser().then(data => {
            const user = data.user;
            const { documents } = getCollection(
                 'Premium', 
                 ['userId', '==', user.value.uid]
            )
            Profile = documents;
        }).catch(err => {
            console.log(err);
        })
    
        console.log(Profile)
    
        return { Profile }
      }
    }
    

    getCollection also sounds like a function that does a call to the server and probably is async.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search