0

I want to add a new data on my real time database. However Database deletes old data and write new data. My data scheme like that :

enter image description here

And I want to add a new user on rooms/roomid/users/

My code part :

joinRoom = async (callback = f => f, roomId) => {
        
        currentRoomUid = roomId
        var username = ''
        await database().ref(`/users/${auth().currentUser.uid}`).once('value', function (snap) {
            username = snap.val().username
        })

        const room = database().ref(`/rooms/${roomId}`);
        await room.set({
            isStart: true,
            currentQuestionIndex: 0
        });

        const usersRef = database().ref(`/rooms/${roomId}/users`)
        usersRef.child(auth().currentUser.uid).set({
            username: username,
            skor: 0
        });

        callback(roomId)
    }

The important point here is where I add the user. I use the set method. How can I fix it ? I want to add the second user.

The Problem

Old Data

enter image description here

After adding operation

enter image description here

Alperen ARICI
  • 204
  • 6
  • 13
  • Calling `usersRef.child(auth().currentUser.uid).set(...)` overwrites the data at `usersRef.child(auth().currentUser.uid)`. But that seems correct to me. What do you want it to do instead? – Frank van Puffelen May 03 '20 at 14:56
  • @FrankvanPuffelen For Example I want to add a new user that's key is 2. And old user's key is 1. so I'm sure the Key of two users is not the same. – Alperen ARICI May 03 '20 at 15:11

2 Answers2

2

Update following your comments:

If you want to add different users under the rooms/423c34.../users node, you need to pass different values to the child() method. For example:

        const usersRef = database().ref(`/rooms/${roomId}/users`)
        await usersRef.child('userKey1').set({  
            username: username1,
            skor: 0
        });

        await usersRef.child('userKey2').set({   
            username: username2,
            skor: 0
        });

If I correctly understand your question, the following adaptations should do the trick:

joinRoom = async (callback = f => f, roomId) => {
        
        currentRoomUid = roomId
        var username = ''
        const snap = await database().ref(`/users/${auth().currentUser.uid}`).once('value');
        const username = snap.val().username;
    
        const room = database().ref(`/rooms/${roomId}`);
        await room.set({
            isStart: true,
            currentQuestionIndex: 0
        });

        const usersRef = database().ref(`/rooms/${roomId}/users`)
        await usersRef.child(auth().currentUser.uid).set({   //Note the await here
            username: username,
            skor: 0
        });

        callback(roomId)
    }

Note that you didn't await the last call to the set() method, so most probably the callback was executed before the new user was persisted to the Database.


Note also that you may use the update() method, to "perform simultaneous updates to multiple locations in the JSON tree with a single call".

Community
  • 1
  • 1
Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
  • Unfortunately. this solutin didn't work. It still deletes old data and then add new data – Alperen ARICI May 03 '20 at 15:03
  • It is not clear what you exactly mean by old data and new data. Look at Frank comment above, he has a similar question. As soon as you use `auth().currentUser.uid` for calling `child()`, you will always overwrite the same node, which corresponds to the authenticated user. How do you differentiate the users, i.e. the old data and new data. – Renaud Tarnec May 03 '20 at 15:06
  • For example, the old data belongs to a user. This user's key is 1 name Frank and the user I want to add is Bob and Key 2. I am sure that the key of the old data is not the same as the key of the new data. – Alperen ARICI May 03 '20 at 15:10
  • Yes you are right. I am sure it has different key but I try again with static datas. – Alperen ARICI May 03 '20 at 15:14
  • So you need to pass keyX to `usersRef.child(auth().currentUser.uid).set(...)` as follows `usersRef.child('keyX').set(...)` – Renaud Tarnec May 03 '20 at 15:15
  • I added two picture on my question – Alperen ARICI May 03 '20 at 15:33
  • I solved my problem. I did not notice the effect of the code block I wrote before. Unfortunately the problem was caused by it. Since I set the same room before, the room was completely deleted and added again. Sorry for stolen your time. Thanks. – Alperen ARICI May 03 '20 at 15:49
1

.set() method will delete your old data and will create new data. so when you using room.set, you deleting everything in room. that's include users. so every time user enters a room he will delete the previous user and add himself instead. you should use room.update like this:

const room = database().ref(`/rooms/${roomId}`);
    await room.update({
        isStart: true,
        currentQuestionIndex: 0
    });

if you want to know better the different between set and update read the answer for this question: Firebase update vs set

here is the full code you should use:

joinRoom = async (callback = f => f, roomId) => {

    currentRoomUid = roomId
    var username = ''
    await database().ref(`/users/${auth().currentUser.uid}`).once('value', function (snap) {
        username = snap.val().username
    })

    const room = database().ref(`/rooms/${roomId}`);
    await room.update({
        isStart: true,
        currentQuestionIndex: 0
    });

    const usersRef = database().ref(`/rooms/${roomId}/users`)
    usersRef.child(auth().currentUser.uid).set({
        username: username,
        skor: 0
    });

    callback(roomId)
}
israel
  • 73
  • 1
  • 12