Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

170
Vistas
Pass firebase reference to function, and get return value

I'm trying to create a function that check if mooving bullet is hitting players.

The code simplified - shoot() is moving the bullet, and check_if_bullet_hit_player(bulletRef) gets a bullet ref, and checks if the bullet is hitting any player.

This is my code:

function shoot(){
  // ... moving bullet code
  const bulletRef = firebase.database().ref(`bullets/${bulletKey}`);
  if(check_if_bullet_hit_player(bulletRef)){
      alert("player got hit");
      bulletRef.remove();
  }
}
function check_if_bullet_hit_player(bulletRef){
  bulletRef.once("value").then(function(snapshot) {
    //for simplicity I just return true - player got hit
    return true;
  }
}

The code is not triggering the alert(). After reading this question I think the problem with the asynchrony, but how do I pass parameters to the function, and get the function's return value.

EDIT:

This is the full check_if_bullet_hit_player() function, which I loop over the players, and checks if the bullet is <0.5 to a player (if so - its count as a hit):

function check_if_bullet_hit_player(bulletRef){
  //bulletRef.once("value").then(function(snapshot) {
  return bulletRef.get().then(snapshot => {
    let bulletX = snapshot.val().x;
    let bulletY = snapshot.val().y;
    let shooterId = snapshot.val().shooterId;

    //loop over players
    const allPlayersRef = firebase.database().ref(`players`);
    allPlayersRef.once("value", (snapshot) => {      
      players = snapshot.val() || {};

      Object.keys(players).forEach((key) => {
          if(getDistance(players[key].x, players[key].y, bulletX, bulletY) < 0.5){

            if(players[key].id != shooterId){ //not the shooter
              return true;
            }
  // ...
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Indeed the problem comes from the fact the once() method is asynchronous. But you also forget to return the promises chain in the check_if_bullet_hit_player() function.

The following, using then() as you do in your question, should do the trick:

function shoot() {
    // ... moving bullet code
    const bulletRef = firebase.database().ref(`bullets/${bulletKey}`);
    check_if_bullet_hit_player(bulletRef)
        .then(result => {
            if (result)
                bulletRef.remove();
        })
}

function check_if_bullet_hit_player(bulletRef) { 
    return bulletRef.get().then(snapshot => {  // See return at the beginning, and also that we use get()
       return snapshot.exists();  // I think you should check if the snapshot exists
    });
}

Note that the shoot() function is also asynchronous. So if you chain it with other function call, you need to use then() (and return the promises chain) or async/await.


Edit following your comment and your question update:

Again you are not returning the promise chain. You can modify it as follows, but I would recommend you use the every() method which "executes the provided callback function once for each element present in the array until it finds the one where callback returns a falsy value"

function check_if_bullet_hit_player(bulletRef) {
    
    let bulletX;
    let bulletY;
    let shooterId;    

    return bulletRef.get().then(snapshot => {
        bulletX = snapshot.val().x;
        bulletY = snapshot.val().y;
        shooterId = snapshot.val().shooterId;

        //loop over players
        const allPlayersRef = firebase.database().ref(`players`);
        return allPlayersRef.get();  // HERE we chain the promise
    })
        .then(allPlayersSnap => {
            players = allPlayersSnap.val() || {};
            let result = false;

            Object.keys(players).forEach((key) => {
                if (getDistance(players[key].x, players[key].y, bulletX, bulletY) < 0.5 && players[key].id != shooterId) {
                    result = true;
                }
            });
            return result;
        });

}

Extra note

It seems these functions are executed in the front end (you use firebase.database()...) You should probably do the calculations in the back-end, e.g. via a Cloud Function, to avoid possibilities for a malicious user to fake the results.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda