Hi I’m trying to create an update page so that a user can update their data in a firestore database but the problem I am having is once the form is submitted to update or the page is reloaded the userId is no longer there so I am trying to use pinia to store the userId so when the form is submitted for update it can retrieve the userId from there and update the data in the database.
The problem is I’m still learning and I’m not sure how to actually save the userId in the store and am having trouble figuring it out, I’ve stored a count before for a simple counter and I’ll put that in below as well as what I’ve currently got for the update page so you can know where I’m at.
The counter vue
<script setup>
defineProps({
msg: String,
})
import { useCounterStore } from '../store/counter'
import { storeToRefs } from 'pinia'
import { ref } from 'vue'
const store = useCounterStore()
const { count, doubleCount } = storeToRefs(store)
// the increment action can just be destructured
const { increment, clearCount } = store
const show = ref(false)
</script>
<template>
<h1>{{ msg }}</h1>
<div class="card">
<button type="button" @click="increment">count is {{ count }}</button>
<button type="button" >double count is {{ doubleCount }}</button>
<button type="button" @click="clearCount">Clear count</button>
<p>
Edit
<code>components/HelloWorld.vue</code> to test HMR
</p>
</div>
</template>
The javascript pinia store
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
function clearCount() {
count.value = 0
}
return { count, doubleCount, increment, clearCount }
},
{
persist: true,
},
)
And here is my update page.vue with no store attched
<script>
import getCollection from '../Composables/getCollection';
import getUser from '../Composables/getUser';
import getPremium from "../Composables/getPremium.js";
import { ref } from "vue";
import useDocument from '../Composables/useDocument';
const {Premium, error, load} = getPremium();
load();
export default{
setup() {
const Name = ref('')
const detail1 = ref('')
const detail2 = ref('')
const detail3 = ref('')
const detail4 = ref('')
const detail5 = ref('')
const details = ref('')
const detail6 = ref('')
const detail7 = ref('')
const detail8 = ref('')
const detail9 = ref('')
const { user } = getUser()
const { documents: Premium } = getCollection(
'Premium',
['userId', '==', user.value.uid]
)
const { updateDoc } = useDocument('Premium', Premium.id)
const createProfile = async () => {
const res = await updateDoc({
Name: Name,
detail1: detail1,
detail2: detail2,
detail3: detail3,
detail4: detail4,
detail5: detail5,
details: details,
detail6: detail6,
detail7: detail7,
detail8: detail8,
detail9: detail9,
})
}
return { Name, detail1, detail2, detail3, detail4, detail5, details, detail6, detail7,
detail8, detail9,
createProfile, Premium }
}
}
</script>
<template>
<br><br>
<div v-if="error">{{ error }}</div>
<div v-if="Premium" class="Profile">
<div v-for =" Premium in Premium" :key="Premium.id">
<p class="text-5xl text-red-700 font-serif">Your Profile</p>
<p class="text-5xl text-red-700 font-serif">{{ Premium.Name }}</p>
<br><br>
<br><br>
<router-link :to="{ name: 'Premium_Edit', params: { id: Premium.id }}">
<p class="bg-neutral-800 hover:bg-neutral-900 active:bg-neutral-800 hover:text-neutral-400 hover:scale-105 text-red-700 w-64 p-4 rounded-xl shadow cursor-pointer inline-block m-10 transition ease-in-out duration-300 drop-shadow-2xl"></p>
</router-link>
<p class="text-3xl text-red-700 font-serif text-left mx-4 md:mx-36 lg:mx-36 xl:mx-36 2xl:mx-36">Details</p>
<hr><br>
<div class="grid gap-4 grid-cols-2 grid-rows-fit md:grid md:gap-4 md:grid-cols-4 md:grid-rows-4">
<p class="font-bold">Location:<br>{{ Premium.Location }}</p>
<p class="font-bold">details:<br></p>
<p class="font-bold">detail4:<br>{{ Premium.detail4 }}</p>
<p class="font-bold">detail2:<br>{{ Premium.detail2 }}</p>
<p class="font-bold">detail7:<br>{{ Premium.detail7 }}</p>
<p class="font-bold">detail6:<br>{{ Premium.detail6 }}</p>
<p class="font-bold">detail8:<br>{{ Premium.detail8}}</p>
<p class="font-bold">detail5:<br>{{ Premium.detail5 }}</p>
<p class="font-bold">detail1:<br>{{ Premium.detail1 }}</p>
<p class="font-bold">detail3:<br>{{ Premium.detail3 }}</p>
</div><hr>
</div><hr><br><br><br><br>
<p class="text-5xl text-red-700 font-serif">Edit Your Profile</p>
<br>
<form @submit.prevent="createProfile">
<div id= "app">
<div class="mx-20 grid gap-y-4 grid-cols-1 grid-rows-fit md:mx-80 md:grid md:gap-x-60 md:gap-y-4 md:grid-cols-2 md:grid-rows-fit md:justify-center lg:mx-80 lg:grid lg:gap-x-60 lg:gap-y-4 lg:grid-cols-2 lg:grid-rows-fit lg:justify-center xl:mx-80 xl:grid xl:gap-x-60 xl:gap-y-4 xl:grid-cols-2 xl:grid-rows-fit xl:justify-center 2xl:mx-80 2xl:grid 2xl:gap-x-60 2xl:gap-y-4 2xl:grid-cols-2 2xl:grid-rows-fit 2xl:justify-center">
<input v-model="Name" required type="text" placeholder="Name" class="h-8 w-fit bg-neutral-300 active:bg-neutral-500 focus:bg-neutral-500 rounded shadow">
<input id="detail1" v-model="detail1" required type="text" placeholder="detail1" class="h-8 w-fit bg-neutral-300 active:bg-neutral-500 focus:bg-neutral-500 rounded shadow ">
<input id="detail2" v-model="detail2" required type="text" placeholder="detail2" class="h-8 w-fit bg-neutral-300 active:bg-neutral-500 focus:bg-neutral-500 rounded shadow">
<input id="detail3" v-model="detail3" type="text" required placeholder="detail3" class="h-8 w-fit bg-neutral-300 active:bg-neutral-500 focus:bg-neutral-500 rounded shadow ">
<input id="detail4" v-model="detail4" type="text" required placeholder="detail4" class="h-8 w-fit bg-neutral-300 active:bg-neutral-500 focus:bg-neutral-500 rounded shadow">
<input id="detail5" v-model="detail5" type="text" required placeholder="detail5" class="h-8 w-fit bg-neutral-300 active:bg-neutral-500 focus:bg-neutral-500 rounded shadow">
<input id="details" v-model="details" type="text" required placeholder="details" class="h-8 w-fit bg-neutral-300 active:bg-neutral-500 focus:bg-neutral-500 rounded shadow">
<input id="detail6" v-model="detail6" required type="text" placeholder="detail6" class="h-8 w-fit bg-neutral-300 active:bg-neutral-500 focus:bg-neutral-500 rounded shadow">
<input id="detail7" v-model="detail7" required type="text" placeholder="detail7" class="h-8 w-fit bg-neutral-300 active:bg-neutral-500 focus:bg-neutral-500 rounded shadow">
<input id="detail8" v-model="detail8" required type="text" placeholder="detail8" class="h-8 w-fit bg-neutral-300 active:bg-neutral-500 focus:bg-neutral-500 rounded shadow">
</div>
<br>
<p class="text-2xl text-red-700 font-serif">Location</p><br>
<select id="location" v-model="Location" class="h-8 w-30 bg-neutral-300 active:bg-neutral-500 focus:bg-neutral-500 rounded shadow ">
<option>Sydney</option>
<option>Melbourne</option>
<option>Canberra</option>
<option>Brisbane</option>
</select><br><br>
<p class="text-2xl text-red-700 font-serif">Photos</p> <br> <br>
<input type="file" v-on="Pic1" @change="handleChange" class="file:bg-neutral-800 file:hover:bg-neutral-900 file:active:bg-neutral-800 file:text-red-700 file:hover:text-neutral-400 file:hover:scale-105 file:text-lg file:w-36 file:p-1 file:rounded-xl file:shadow file:cursor-pointer inline-block file:transition ease-in-out duration-300 drop-shadow-2xl"><br> <br>
<div class="error">{{ fileError }}</div>
</div>
<button class="bg-neutral-800 hover:bg-neutral-900 active:bg-neutral-800 hover:scale-105 text-red-700 hover:text-neutral-400 text-xl w-64 p-4 rounded-xl shadow cursor-pointer inline-block m-10 transition ease-in-out duration-300">Update your Profile</button>
<br><br><br></form>
<br><br>
</div>
<div v-else>
<div class="spin"></div>
</div>
</template>
I don’t have a store in Javascript for this yet as I said I’m a little unsure and to be honest a bit confused about what to do the user from getUser is just this
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
Main.js for counter
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { createPinia } from 'pinia'
import piniaPluginPersistedState from "pinia-plugin-persistedstate"
const pinia = createPinia()
pinia.use(piniaPluginPersistedState)
createApp(App).use(pinia).mount('#app')
Main.js for database user update
import { createApp } from 'vue'
import app from './App.vue'
import './style/index.css'
import router from '../src/router/index'
import { createPinia } from 'pinia'
import InstantSearch from 'vue-instantsearch/vue3/es';
createApp(app).use(router).use(createPinia()).use(InstantSearch).mount('#app')
I know thats a lot to read through and I’m sorry but as I said I’m just really confused about how to do it and how to make the profile page then get that userId from the store when it needs to as well as setting the whole thing up, if anyone could show me how or leave some links of examples in documentation that show you how to store a userId in pinia and then retrieve it that would be great thanks.