Reputation: 675
This is my first time using firebase with react and I am trying to make an app where a user can insert songs in his private playlist in firebase firestore :
this is how I store a created user :
firebase.js
const app = firebase;
export const auth = app.auth();
export default app;
export const storage = firebase.storage();
export const db = firebase.firestore();
export const userCollection = db.collection('users');
export const CreateUser = async (email,password,username)=>{
const authResult = await auth.createUserWithEmailAndPassword(email,password);
userCollection.doc(authResult.user.uid)
.set({
created:firebase.firestore.FieldValue.serverTimestamp(),
Email:email,
userName:username,
Playlist:[],
});
}
export const insertSong = async (song , email ) =>{
await userCollection.where('Email' , '==' , email)
.get()
.then(snapshot=>{
snapshot.forEach(snap=>{
//if I console.log(snap.data()) my data is correct
snap.data().Playlist = [...snap.data().Playlist,song];
})
})
.catch(err=>{
console.log(err);
})
}
where with the created user I set an empty playlist array as well
Now in another component, I try to update the playlist for the specific user
Upload.js
import {React , useState} from 'react';
import {insertSong, storage} from '../firebase';
import {useAuth} from './UserContext';
export default function Upload(){
const {user} = useAuth(); //this is how I access the email of the user
const [disabled , setDisabled] = useState(false);
const [url , setUrl ] = useState(null);
const checkSong = async (e)=>{
const song = e.target.files[0];
if(song){
try{
const songsRef = storage.ref('songs').child(song.name);
setDisabled(true);
await songsRef.put(song);
console.log('Song has been inserted');
const result = await songsRef.getDownloadURL();
setUrl(result);
//if I do console.log(disabled) in this line it is false not true !
insertSong(url,user.email); //this is where the problem happens
}catch(err){
console.log(err);
}
setDisabled(false);
}
}
return (
<div>
<h1> Upload a song : </h1>
<input type = "file" accept="audio/mp3,audio/*;capture=microphone" disabled = {disabled} onChange={checkSong}/>
</div>
);
}
so when I check the playlist of the user on the firebase website it is empty. I think there is a problem with the asynchronicity here as my disabled variable becomes false before I try to insert a song in the user's playlist as I have commented above. I would really appreciate your help here.
Upvotes: 1
Views: 717
Reputation: 675
I created a new method to update the playlist array by getting the doc id as input and updating the document
const updateArray = async (id,song)=>{
const document = userCollection.doc(id);
await document.update({
Playlist: firebase.firestore.FieldValue.arrayUnion(song)
}).catch(err=>{
console.log(err);
})
}
export const insertSong = async (song , email ) =>{
await userCollection.where('Email' , '==' , email)
.get()
.then(snapshot=>{
snapshot.forEach(snap=>{
updateArray(snap.id,song)
})
})
.catch(err=>{
console.log(err);
})
}
The only problem is that if the playlist is empty it adds a null element at first and then works perfectly .
Upvotes: 0
Reputation: 558
inside insertsong try this
try{
var snapshot = await userCollection.where('Email' , '==' , email);
if(!snapshot.empty){
var docsnap = snapshot.docs[0];
var playlist = docsnap.data().Playlist;
//if I console.log(snap.data()) my data is correct
playlist = [...song];
docsnap.ref.update({"Playlist": playlist});
}
}
catch { (err)=>{
console.log(err);
}};
Upvotes: 1