Pass data from a Firebase JavaScript callback function in the Data Access Layer (DAL) to another function in the controller

I have been developing a basic chat application that enables users to send messages in a group chat and see them instantly updated. To achieve this, I opted for Firebase and spent time familiarizing myself with its web API. However, I encountered difficulties when attempting to manually create a user authentication system or retrieve a list of values for another function.

My approach involves following an MVC pattern, where HTML forms trigger event handlers in global.js, which then call corresponding methods in the controller file, leading to actions in the DAL. The DAL interacts with remote Firebase to perform the requested tasks.

The issue arises after the once event handler is triggered. Although the controller executes the checkUserLogin() method, the variable loginValid does not get assigned anything. It seems that the execution reaches the end of the event handler but abruptly discontinues. I have read about asynchronous JS, but my understanding is limited.

My goal is simple: fetch a list from Firebase, validate it, pass the result from the DAL to the controller, and operate on the outcome within the controller. Real-time updates are not necessary as I occasionally require a current snapshot of data from the Firebase list to carry out other functions.

Below is the relevant file structure. global.js manages event handlers for HTML page events and selects the appropriate controller action (security_controller.js) which triggers the necessary DAL action (security_dal.js).

global.js

$(document).ready(function() {
    $("#btnSubmitLogin").on("click", btnSubmitLogin_click);
});

function btnSubmitLogin_click() {
     doUserLogin();
}

security_controller.js

function doUserLogin() {
    var username = $("#txtLoginUsername").val();
    var password = $("#txtLoginPassword").val();

    //Check if user is logged in and react accordingly
    var loginValid = checkUserLogin(username, password);

    if (loginValid) {
        navigateToPage("pageHome");
        $("#successMessageLogin").text("Success validating user");
    }
    else {
        navigateToPage("pageLogin");
        $("#errorMessageLogin").text("Error validating user");
    }
}

security_dal.js

function checkUserLogin(username, password) {
    var foundUser = null;
    var loginValid = false;

    fb_ref.once("value", function(snapshot) {
        var list = snapshot.val();

        for (var i in list) {
            if (list[i].username === username && list[i].password === password) {
                foundUser = list[i];
                break;
            }
        }           

        return loginValid;
    });

    if (foundUser !== null) {
        console.info(foundUser.username);
        console.info(foundUser.password);
        loginValid = true;
    }

    return loginValid;
}

I searched for similar queries but could not find a solution. In one question/answer thread linked below, the response mentioned asynchronous JavaScript and resolved the issue by placing the code that needs to execute after retrieving values inside the callback function. Nonetheless, this contradicts my aim of adhering to the "MVC pattern." The DAL should not directly interact with the view but rather relay returned values back to the controller.

Firebase Query Inside Function Returns Null

This is the methodology I intend to follow:

  • global.js invokes btnSubmitLogin_click()
  • btnSubmitLogin_click() calls doUserLogin in the controller
  • doUserLogin in the controller invokes checkUserLogin in the DAL
  • checkUserLogin in the DAL retrieves a list of users from Firebase and checks for credentials match
  • checkUserLogin in the DAL returns true/false to the controller and assigns it to the variable loginValid
  • The controller decides how to handle this information, updating the view as necessary

Note: While aware of Firebase's built-in authentication, I am creating a simplified version for learning purposes. Thus, I only require a data array/list for manipulation in the controller. Despite filtering/sorting capabilities, I prefer checking users using this method to understand how to retrieve a list.

If there are alternative approaches or corrections to be made due to my novice knowledge of Firebase, please advise. Thank you!

Answer №1

A crucial element here is the usage of asynchronous processing. One way to tackle this issue is by creating your own callbacks, allowing you to maintain control over where the logic should be executed.

To implement this strategy in the current scenario, consider adding a third parameter to the checkUserLogin function:

checkUserLogin(username, password, function(foundUser) {

     if (foundUser) {
         navigateToPage("pageHome");
         $("#successMessageLogin").text("User validation successful");
     } else {
        navigateToPage("pageLogin");
        $("#errorMessageLogin").text("User validation error");
     }
});

Then define the checkUserLogin function as follows:

function checkUserLogin(username, password, callback) {
    fb_ref.once("value", function(snapshot) {
        var list = snapshot.val();
        var foundUser;

        for (var i in list) {
            if (list[i].username === username && list[i].password === password) {
                foundUser = list[i];
                break;
            }
        }           
        callback(foundUser)
    });
}

(It's important to note the issue of storing unencrypted passwords, among other security concerns)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using AngularJS to populate dropdown options with data from JSON objects

I have a JSON file that looks like this: var myJson = { "Number of Devices":2, "Block Devices":{ "bdev0":{ "Backend_Device_Path":"/dev/ram1", "Capacity":"16777216", "Bytes_Written":9848, "timestamp":"4365093 ...

My pathways are clearly mapped out, yet express is returning a frustrating 404 error

After exhausting all the similar posts on StackOverflow without finding a solution... Let's take a look at my app.js, which is the first file that the express library seeks when launching the app right after my server.js file responsible for setting ...

In the ajax call, an empty JSON array object is sent as the data

Utilizing JSON data as a parameter for an ajax call: var startDate = dateFormatForSave($("#start_date").val().trim()); var arrayOfStudentsInfo = []; var table = $("#selected_students"); table.find('tr').each(function(i, el) { var rowId = $( ...

Develop an interactive AngularJS application with a dynamic Bootstrap table feature

I'm in the process of transitioning my existing jQuery code to AngularJS. One part of the code involves creating a dynamic Bootstrap table based on JSON data retrieved from a Spring REST service. The snippet below shows the jQuery code used to create ...

console displaying indentation problems with laravel and vue

I am currently utilizing Vue within Laravel and encountering a multitude of indentation errors in the console. Here is an excerpt from my package.json file: "private": true, "scripts": { "clean": "rimraf public/build", "build": "npm run clean & ...

Using jQuery to transfer data via POST method

I'm currently working on integrating a third-party tool into our website. The tool requires the use of a form with the post method to send data to their site. Is there a way for me to replicate this action without relying on the form tag? I am not ver ...

Combining Nested Objects in MongoDB

I have searched extensively for a solution but I am struggling to find a resolution to my issue. I have two MongoDB (Node.JS) collections: user & statistics. My goal is to merge the results using aggregate. Below are the structures of the collection ...

Harnessing the Power of Google Apps Scripts: Mastering the Art of Handling Comma-Separated Spreadsheet Values Transformed

I have a spreadsheet where column 1 contains source file IDs, with each cell holding only one ID. Column 2 has destination file IDs, where cells contain multiple IDs separated by commas. I utilize a script to retrieve these values and perform various opera ...

Troubleshooting Problems with Promises in Node.js Express

I am currently developing a Node.JS/Express application with Jade as the template engine, but I am encountering some unexpected behavior. The issue arises when trying to retrieve data from a mock API and pass it to my Jade template. Despite confirming tha ...

One way to showcase a single piece of data without the need for looping is by utilizing the `

I am encountering an issue. Why does the insertAdjacentHTML("afterend") output keep looping? I only want to display "1" once, not repeatedly. var btn = document.getElementById("btnClick"); btn.addEventListener("click", function (e) { e.preventDefaul ...

Unable to append XML nodes using jQuery's parseXML function, but able to append font

Jquery : $.get("config.xml",function(xml){ $(xml).find("config").find("images").append("<image><url>../demo/Headline/2012/12/20/0/0/A/Content/8/Web201212_P8_medium.jpg</url><name></name><redirect>none</r ...

Can someone help me figure out how to increase the values of two specific attributes within a class?

Currently facing a challenge with adjusting the number of likes and comments using increment for properties 'numberOfLikes' and 'comments'. Unsure whether to utilize a for loop or just the increment operator. Still new to coding, so apo ...

Efficiently run multiple Node-written apps on a single server

I currently have a single VPS and would like to host multiple node.js apps on it, similar to how Apache or Nginx works. I am using Nginx as a proxy, but I have concerns. As you know, one of the key features of Node.js is its non-blocking I/O and sing ...

Tips for interpreting information from a JSON array that has been stringified, looping through the data, and utilizing it effectively

I'm currently exploring Node JS packages and I need some guidance. Here is an example of the JSON data that I have: [{ "name":"SpiderMan", "description":"Superhero", "head_id":"29", "domain_name":"spiderman.com" }] I am trying to figure out how to ...

Tips for displaying NoOptionsText in MaterialUI Autocomplete based on a specific condition

When using a Material UI autocomplete feature, the items are selected based on the first 3 letters typed. For example, if you're searching for all "Pedros" in your database, typing "Ped" will bring up results starting with those letters. The issue ar ...

What methods are commonly used to calculate the bitsPerSecond rate for media recording?

Is there a specific formula that combines frames per second and resolution to determine the bits per second for video encoding? I'm struggling to figure out the appropriate values to use for specifying the bits per second for 720p, 1080p, and 4k video ...

Express: when req.body is devoid of any data

My server code using Express: const express = require('express'); const exphbs = require('express-handlebars'); const path = require('path'); const bodyparser = require('body-parser'); const app = express(); cons ...

"Troubleshooting jQuery html() Function Issue in Firefox: Dealing with an Unterminated

Trying to insert the following string into a <p> element: (without specified charset) Цена: 4,80 BGN Поддръжка: (directly from .XML file) &#1062;&#1077;&#1085;&#1072;: 4,80 BGN Encountering ...

What is the most optimal method for transforming this array of objects into a different format?

My array consists of objects structured like this: [ {prop1: valueA, prop2: valueB, prop3: valueC}, {prop1: valueD, prop2: valueE, prop3: valueF}, ... ] I am looking to transform this array into objects with a different structure: [ {x: valueA, y: value ...

Reorder elements in CSS Grid

I've been working with a css-grid and it's almost there, but I'm stuck on reordering the items in a specific way. Currently, the html layout is set as “1, 2, 3, 4,…10”, but for smaller screens, I want the visual order to be “1, 2, 4 ...