B4J Tutorial Beginning Firebase Database in JavaScript: CRUD-ing around

Hi there...

Anyway, this should not be long. Many moons I was requested to work on a firebase wrap for ABM. Im not there yet, but this should be a start. I'm still getting a hang of it and more will follow as I make more progress. I'm testing this for something I'm doing, however you can use this for your webapps easily.

Some silly assumptions:

You can write some javascript code.

Steps

1. First things first, goto Firebase console and create an app https://console.firebase.google.com
2. Get your app ish together, appID, apiKey etc etc etc from google.
3. Now for some javascript, you can create an app.js file and link it to your html file... or perhaps execute this via websockets eval methods inside your ABM app.
4. Ensure that on the Rules tab you update the permissions to true for read and write and publish them.

Let's type ahead...

B4X:
// Initialize Firebase
var fbconfig = {
apiKey: "<api-key>",
authDomain: "<domain>.firebaseapp.com",
databaseURL: "https://<db-thingy>.firebaseio.com",
projectId: "<projectid>",
storageBucket: "<storebucket>",
messagingSenderId: "<senderid>"
};
firebase.initializeApp(fbconfig);

replace the stuff inside <> with your own details from the console. This I guess is to ensure that your firebase thing will work. Next we need to get reference to the db. Continue to type..

B4X:
// Get a reference to the entire database
var fbdatabase = firebase.database().ref();

We want to store some records in a "table", let's create the table. The name is "recommendations". If the table does not exist, as soon as a record is added to it, it will come into existence.

B4X:
var recommendations = fbdatabase.child("recommendations");

We also want a way to return the last record added to the table, lets write a function..

B4X:
function GetLastrecommendations(){
    var lastrec = new Object();
    recommendations.limitToLast(1).on('child_added', function(childSnapshot) {
      lastrec = childSnapshot.val();
    });
    return lastrec;
}

This will return an object just like your Map object in b4j, or rather a JSON string like representation of your data.

Now, let's add a record to the table. You can link this with a button click event.

B4X:
var record = new Object();
record.title = "Why I love B4J";
record.presenter = "Anele Mashy Mbanga";
record.link = "https://www.mbangas.com/blog/nothing_there";
var eRecord= JSON.stringify(record);
recommendations.push(eRecord);

This creates a new record and pushes it to the list of records available and creates a unique key for it.

Now let's retrieve the last record we added to the table...

B4X:
var lastrecommendation = GetLastrecommendations();
console.log(lastrecommendation);

Off course, you can do whatever you want with it...

For now that concludes the C for create for our CRUD firebase functionality.

To be continued...
 

Attachments

  • firebase.txt
    9.1 KB · Views: 386
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Looking at some other intersting things...

Are you online?

B4X:
$('#btnconnected').on('click', function (e) {
var connectedRef = firebase.database().ref(".info/connected");
var isconnected = false;
connectedRef.on("value", function(snap) {
if (snap.val() === true) {
isconnected = true;
} else {
isconnected = false;
}
});
console.log(isconnected);});

Sign in Anonymously

Select Authentication > Sign-In-Methods and enable the functionalities you want...

B4X:
$('#btnanonymoussignin').on('click', function (e) {
firebase.auth().signInAnonymously()
.then(function() {
M.toast({html:'Signed In!', displayLength:3000, classes:'rounded white-text green'})
}).catch(function(error) {
M.toast({html:error.message, displayLength:3000, classes:'rounded white-text red'});
});});

Sign In with Google (this opens up a screen prompt for your email address and password if you are not signed in)

B4X:
var provider = new firebase.auth.GoogleAuthProvider();
function googleSignin() {
firebase.auth()   
.signInWithPopup(provider).then(function(result) {
var token = result.credential.accessToken;
var user = result.user;
console.log(token)
console.log(user)
}).catch(function(error) {
M.toast({html:error.message, displayLength:3000, classes:'rounded white-text red'});
});
}


Sign Up using email and password.

B4X:
$('#btnsignup').on('click', function (e) {
var emailaddress = $('#emailaddress').val().trim();
var password = $('#password').val().trim();
firebase.auth().createUserWithEmailAndPassword(emailaddress, password).catch(function(error) {
M.toast({html:error.message, displayLength:3000, classes:'rounded white-text red'});
});});

Sign In using email and password

B4X:
$('#btnsignin').on('click', function (e) {
var emailaddress = $('#emailaddress').val().trim();
var password = $('#password').val().trim();
firebase.auth().signInWithEmailAndPassword(emailaddress, password).catch(function(error) {
M.toast({html:error.message, displayLength:3000, classes:'rounded white-text red'});
});});
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
The first post dealt with setting up firebase and then creating a record. The assumption was that firebase generates the keys for you. This might work for some particular circumstances, but we want to define our own keys and store the values in them. So here we go.

Create.png


Validating Keys

Keys in firebase should not produce certain values, then we need a function to clean the key everytime we query / save it.

B4X:
function CleanKey(value){
    value = Replace(value,'.','');
    value = Replace(value,'#','');
    value = Replace(value,'$','');
    value = Replace(value,'/','');
    value = Replace(value,'[','');
    value = Replace(value,']','');
    return value;
    }

I have then updated the Create method so that it can return the key that was created so one can refer to this again anywhere.

Creating a record with a unique id generated by firebase...

B4X:
$('#btnsaveprofile').on('click', function (e) {
var emailaddressvalue = $('#emailaddress').val().trim();
var passwordvalue = $('#password').val().trim();
var profile = new Object();
profile.emailaddress = emailaddressvalue;
profile.password = passwordvalue;
var eProfile= JSON.stringify(profile);

// Get a key for a new profiles record.
    var profilesKey = profiles.push().key;
    var profilesupdates = {};
    profilesupdates['/profiles/' + profilesKey] = eProfile;
    fbdatabase.update(profilesupdates);
    var profileKey = profilesKey;
console.log(profileKey);
});

As you will notice here, we save the complete JSON representation of the record including email and password. If however we want to save the record by email address, we need to clean the email address and only save the password. One thing one should note though is that any character in your record is counted during data downloads as uploads are free. Thus its rather important to change your 'entity' names to be as small as possible. For example instead of field "emailaddress" or "password" in the saved data, one could use fieldnames "e" and "p". Anyway...

Creating a record with own key

B4X:
$('#btnsaveprofilebyemail').on('click', function (e) {
var emailaddress = $('#emailaddress').val().trim();
var password = $('#password').val().trim();
var profile = new Object();
profile.password = password;
var eProfile= JSON.stringify(profile);

// update record by own key
    var profilesKey = emailaddress;
    profilesKey = CleanKey(profilesKey);
    var profilesupdates = {};
    profilesupdates['/profiles/' + profilesKey] = eProfile;
    fbdatabase.update(profilesupdates);
});

The above assumption is that you had created a 'profiles' table as discussed in the previous posts. From the above, it should be easy to update and delete records using the keys. A topic for another day..

Ta!
 

Mashiane

Expert
Licensed User
Longtime User
Detecting Data Changes

There are a variety of events that happen when data changes on your 'table' aka collection. When these changes happen one can perform other functions, e.g updating the UI by drawing a chart, etc etc, as soon as the data changes.

OnValue i.e. changes to the whole 'table'

This method runs when the app loads and everytime the data changes in the whole collection. I wouldnt use this for large data sets though as the whole collection is downloaded everytime a change is made.

B4X:
fbdatabase.child('profiles').on('value', function (snapshot) {
    var currentData = snapshot.val();
    console.log(currentData);
  });

One can use dot notation to get each data attribute as per entity properties defined.

child_added, child_changed, child_moved, child_removed i.e. changes to single records.

These happen each time a record is added, changed, moved and removed in your table.

B4X:
profiles.on('child_added', function (snapshot) {
var currentData = snapshot.val();
console.log(currentData);
});

profiles.on('child_changed', function (snapshot) {
var currentData = snapshot.val();
console.log(currentData);
});

profiles.on('child_moved', function (snapshot) {
var currentData = snapshot.val();
console.log(currentData);
});

profiles.on('child_removed', function (snapshot) {
var currentData = snapshot.val();
console.log(currentData);
});

And then one can write the appropriate javascript code to perform particular processes in your app.
 

Mashiane

Expert
Licensed User
Longtime User
To summarise the firebase database CRUD (Create-Update-Update-Delete) functionality, we...

Create (this overwites everything for the node)

B4X:
$('#btnsaveprofilebyemail').on('click', function (e) {
var emailaddress = $('#emailaddress').val().trim();
var password = $('#password').val().trim();
var profile = new Object();
profile.password = password;
var eProfile= JSON.stringify(profile);

var profilesKey = emailaddress;
    profilesKey = CleanKey(profilesKey);
    firebase.database().ref('profiles/' + profilesKey).set(eProfile);
});

Update (this updates the various specified attributes)

B4X:
$('#btnupdateprofilebyemail').on('click', function (e) {
var emailaddress = $('#emailaddress').val().trim();
var password = $('#password').val().trim();
var profile = new Object();
profile.password = password;
var eProfile= JSON.stringify(profile);

var profilesUpdate = {};
    var profilesKey = emailaddress;
    profilesKey = CleanKey(profilesKey);
    profilesUpdate['/profiles/' + profilesKey] = eProfile;
    fbdatabase.update(profilesUpdate);
});

Read (this returns the json content of the node)

B4X:
$('#btnread').on('click', function (e) {
var email = $('#emailaddress').val().trim();
var profilesKey = email;
    var single;
    profilesKey = CleanKey(profilesKey);
    var profilesRec = firebase.database().ref('profiles/' + profilesKey);
profilesRec.once('value', function(snapshot) {
  single = snapshot.val();
});
console.log(single);});

Delete (this deletes the node permanently)

B4X:
$('#btndelete').on('click', function (e) {
var email = $('#emailaddress').val().trim();
var profilesKey = email;
    profilesKey = CleanKey(profilesKey);
    firebase.database().ref('profiles/' + profilesKey).remove();
});

The examples above are based on reading content from text boxes in an html page using JQuery and performing actions accordingly. As explained before, firebase database is a key value store db that with this methodollogy you can save and retrieve records to a database. One is able to query the data using some form of JSQL but we wont cover that here.

That's all folks.
 
Top