Tengo dificultades reales para combinar onSnapshot con getDownloadURL en mis acciones y configurarlo en mutaciones para cambiar mi estado en vuex. Sigo recibiendo el error "[vuex] no mutar el estado de la tienda vuex fuera de los controladores de mutación".
Aquí hay una muestra de mi código:
state = () => ({ products:[] }) mutations = { setProducts(state, products) { state.products = products console.log(state.products) }, } actions = { setProducts({commit}) { let colRef = collection(db, 'products') const unsub = onSnapshot(colRef, snapshot => { let products = [] snapshot.docs.forEach(doc => { const imageDownloadURL = getDownloadURL(ref(storage, `${doc.data().imageRef}`)) .then( url => { // console.log(url) products.push({ id: doc.id, name: doc.data().name, price: doc.data().price, description: doc.data().description, imageURL: url }) commit('setProducts', products) }) }) }) }, }Tengo una colección que se ve así:
{ id: 1, name: 'NotPot Orange', price: '8.80', description: 'This is an orange flavour vitamin', imageURL: 'images/notpot1.jpg' },Mi console.log da los datos que quiero en esta salida:
{ id: 'qv1t4f2NfAo9N4YrkXzg', name: 'NotPot Citrus', price: '6.50', description: 'This is a citrus flavour vitamin', imageURL: 'https://firebasestorage.googleapis.com/v0/b/blahblahblah- project.appspot.com/o/images%2Fnotpot5.jpg?alt=media&token=385a5a25-ef2c' },Tengo un getter que agarro en mi v-for:
getters = { products: (state) => { return state.products }, }al igual que:
<feature-product v-for="product in this.$store.getters.products" :key="product.id" :product="product" />¿Me estoy perdiendo algo? Realmente no estoy tan versado con onSnapshot y getDownloadURL, así que siento que es un error en alguna parte. Escuché algo sobre la necesidad de deepClone/deepCopy pero no estoy seguro de lo que eso significa. ¡Cualquier pista o punto en la dirección correcta será de gran ayuda! ¡Gracias por adelantado!
Todavía no estoy 100% seguro de si este es el método correcto, pero lo hice funcionar con {getDocs} from 'firebase/firestore' junto con {ref, getDownloadURL} from 'firebase/storage'
Decidí eliminar la extracción de datos en tiempo real antes mencionada para obtener documentos de una sola vez, por lo que no es exactamente como lo quería, pero pensé que todavía es aplicable a mi caso de uso. Aquí están mis cambios:
actions = { async setProducts({commit}) { let colRef = collection(db, 'products') const querySnapshot = await getDocs(colRef) querySnapshot.forEach((doc) => { let products const imageDownloadURL = getDownloadURL(ref(storage, `${doc.data().imageRef}`)) .then( url => { // console.log(url) products = ({ id: doc.id, name: doc.data().name, price: doc.data().price, description: doc.data().description, imageURL: url }) commit('setProducts', products) }) }) } }cambios en mis mutaciones:
mutations = { setProducts(state, products) { state.products.push(products) console.log(state.products) }, } PD para que se cargue lo antes posible: puede usar enlaces de ciclo de vida beforeCreated() o created() para enviar la acción 'setProducts'.
Espero que esto ayude a cualquier otra persona atascada en algo similar.