11

I have user table and this code.

getOnline code and connected button

var onlineStatus = firebase.database().ref("users/" + firebase.auth().currentUser.uid + "/online");
onlineStatus.set(1);  

and

var dbUser = firebase.database();
var refUser = dbUser.ref("users");


refUser.orderByChild("online").equalTo(1).on("value", function(Data){
    console.log(Data.val(), Data.key);
});

I can already see online=1 users, but I want to randomly get 1 user who has the online = 1.

How can I do this?

Update

I want to build randomly chat. people will match according to the criteria. like Tinder App. Think about it, there is a page and button. When the user presses the button, it will match any online user. and chatting.

firebase users;

users
     VIkvYAtLHxNqAwd722oKenriM7PJz2
        email: "mail@hotmail.com"
        online: 1 
        profile_picture:"https://scontent.xx.fbcdn.net" 
        username: "John Snow"

     DIkvYAtLHxNqAwd722oKenriM7PJz2
        email: "mail2@hotmail.com"
        online: 1 
        profile_picture:"https://scontent.xx.fbcdn.net" 
        username: "Jane Snow"
cnsvnc
  • 714
  • 6
  • 16

1 Answers1

7

You can use the Math.random() function to get a random number (let's call it n) and then get the nth user online:

refUser.orderByChild("online").equalTo(1).on("value", function(Data){
    console.log(Data.val(), Data.key);
    var totalOnline = Data.numChildren(); //get number of online users
    var randomNr = Math.random() * totalOnline;
    var userIndex = parseInt(randomNr, 10); //parse the random number from double to integer
    var currentIndex = 0;
    Data.forEach(function(snap){
        if(currentIndex==userIndex){
            var randomUser = snap.val();
            //Do something with your random user
            break;
        }
        currentIndex++;
    });
});

Also note that if you have a huge app with thousands of users, you might want to limit the query to 50 users to improve the app's performance:

refUser.orderByChild("online").equalTo(1).limitToFirst(50)

Update: To exclude your own user you can check if the random user is you. And if it is, go to the next one:

        if(currentIndex>=userIndex && snap.key != firebase.auth().currentUser.uid){
            var randomUser = snap.val();
            //Do something with your random user
            break;
        }

Update 2: I've discovered that you can't use break on forEach loop. So you can solve that using the solution provided here (use a BreakException):

refUser.orderByChild("online").equalTo(1).on("value", function(Data){
    console.log(Data.val(), Data.key);
    var totalOnline = Data.numChildren(); //get number of online users
    var randomNr = Math.random() * totalOnline;
    var userIndex = parseInt(randomNr, 10); //parse the random number from double to integer
    var currentIndex = 0;
    var BreakException = {};
    try
    {
        Data.forEach(function(snap){
            if(currentIndex==userIndex){
                var randomUser = snap.val();
                //Do something with your random user
                throw BreakException;
            }
            currentIndex++;
        });
    }
    catch(e){
        if(e!== BreakException) throw e;
    }
});
  • thanks for help !!! :) and i dont understand limitToFirst because i will matched filter " age , location and gender all users. example : i have a 1k user in same location . This code all check 1k user and work with limitToFirst(50) ? – cnsvnc Feb 05 '18 at 00:31
  • this code worked but i matched own user . how can i exclude my own user ? because currentUser online = 1 too :/ thanks. – cnsvnc Feb 05 '18 at 01:36
  • My bad @Cœur. The indices changed because I used the hyperlink button on the editor. I'll edit it manually next time. Thanks – Rosário Pereira Fernandes Feb 05 '18 at 07:55
  • @RosárioPereiraFernandes oh, interesting, I wasn't aware of this side effect of using the editor. Thanks for the tip. – Cœur Feb 05 '18 at 08:17
  • @RosárioPereiraFernandes thanks for update but break; showing error so not working. and without break; code is working but all online = 1 users get :S – cnsvnc Feb 05 '18 at 10:16
  • @RosárioPereiraFernandes update comment : multiple users will match each other in this app. So 1 vs 1 will match. like Tinder App – cnsvnc Feb 05 '18 at 10:19
  • @RosárioPereiraFernandes hello again, I want to build randomly chat. people will match according to the criteria. like Tinder App. Think about it, there is a page and button. When the user presses the button, it will match any online user. and chatting. Thanks for your patience. – cnsvnc Feb 06 '18 at 18:12
  • When i add break; error is " no message provided " .and when without break; i matched all online user. I need to match with 1 person. i used console.log(randomUser) @RosárioPereiraFernandes – cnsvnc Feb 06 '18 at 20:40
  • I need to match only 1 person online at that moment. all online users must match one random person. @RosárioPereiraFernandes – cnsvnc Feb 06 '18 at 20:45
  • HI @cnsvnc, how did you handle the multiple filtering on Firebase? For exmaple filter with age, location and gender? – David Dec 20 '19 at 15:26