1

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.

3
  • is the code working till the getDownloadURL part? Are you getting the result url? Commented Nov 21, 2020 at 19:02
  • @p2hari Yes it does Commented Nov 21, 2020 at 19:04
  • ooh , now i got it looking into the code. Inside the snap you are changing the playlist but not persisting it in the firestore. You will need to update the data . Commented Nov 21, 2020 at 19:11

2 Answers 2

1

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);
}};
Sign up to request clarification or add additional context in comments.

1 Comment

It did not work but I found the solution . Thank you very much for your time . Check what I did
0

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 .

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.