I was recently lucky enough to receive a beta invite for Firebase, a Javascript tool that aims to remove or at least reduce the need for a dedicated server. I found their demos pretty convincing and if their claims were true I knew the library would be a great tool for the Part Coder arsenal. One of the demo apps on their site is a simple chat app (https://www.firebase.com/tutorial/#example-chat). I wondered how quickly I could adapt their demo into a prototype Android app. That’s where Application Craft came in. Application Craft is a great tool for creating, testing and deploying mobile applications.
As it turns out it only took a couple of hours; part of that time was learning how to use Firebase. I think if I had to start again from scratch it could probably be done comfortably in under an hour. Not bad for a prototype IM app.
All in all it took under 100 lines of code. The salient points are listed below.
You can check out Application Craft here and Firebase here. I have a handful of beta codes for Firebase. Leave a comment if you're interested in taking one.
Set up
Initialising the Firebase library is dead easy. It just takes one line.
var BASE_URL = 'https://*firebasename*.firebaseIO.com';
var baseRef;
// when app starts initialise the base reference for all Firebase calls
function handler_application_onAppStarted(){
baseRef = new Firebase(BASE_URL);
}
Choosing a chat room
Not strictly necessary for the prototype but I decided to allow the user the option to join an existing chatroom or create their own.
// create a room with a given name, return its Firebase 'url'
function _create_room(name){
return baseRef.push({name:name}).toString();
}
// user has selected a room
// set chatroomRef to the reference of the room, jump to the chatroom page
function _join_room(roomURL){
chatroomRef = new Firebase(roomURL);
app.pageJump("chatroomPage");
}
// user has opted to add a new chatroom
// show the hidden 'new chatroom' interface
function handler_openAddChatroomButton_onClick(mouseev){
app.visible("newChatroomContainer", true);
}
// when the choose room page first shows, populate the list of chatrooms
// so the user can choose one
function handler_chooseRoomPage_onPageShow(){
baseRef.once("value", function(dataSnapshot) {
// need to use the map function to get from what Firebase returns
// to what Application Craft needs to populate the list widget
var rooms_array = jQuery.map(dataSnapshot.val(),
function(value, key){
return { "roomURL" : key, "name" : value.name };
});
app.populateWidget("chatroomListContainer", rooms_array,
{ "chatroomChoiceButton" : "name",
"roomURLLabel" : "roomURL" });
});
}
// the user has clicked the add room button
function handler_addChatroomButton_onClick(mouseev){
var roomName = app.getValue("newChatroomName");
var roomURL = _create_room(roomName);
_join_room(roomURL);
}
// a bit icky this one, there's probably a better way to do it :)
// extract the URL of the selected chatroom from the relevant
// layer of the UI
function handler_chatroomChoiceButton_onClick(mouseev){
var index = _widget.parent().rowIndex();
var rowObj = _widget.parent().parent().getRow(index);
var roomURL = rowObj.w('roomURLLabel').value();
_join_room(BASE_URL+"/"+roomURL);
}
Handling chat events
Now that the user is in the right room it's pretty trivial to send and receive messages.
// user has clicked send text button
// read the message and push it to Firebase
function handler_sendTextButton_onClick(mouseev){
var name = app.getValue("usernameText");
var message = app.getValue("messageText");
chatroomRef.push({ "name":name, "message":message });
app.setValue("messageText", "");
}
// when the page first loads call the Firebase 'on' function
// first param is 'child_added' meaning this will get updated
// every time a child (i.e. message) is added to our room ref
function handler_chatroomPage_onPageShow(){
chatroomRef.on("child_added", function(dataSnapshot) {
var val = dataSnapshot.val();
// check there's something in our returned value
// the first and last values are sometimes empty
if (val.name) {
var new_string = app.getValue("chatLabel") +
val.name + ": " +
val.message;
// chatLabel displays the messages
app.setValue("chatLabel", new_string);
}
});
}
// a token effort towards making this a proper app
// just to illustrate stopping the flow of data from Firebase
// with the 'off' function
function handler_chatroomPage_onPageLeft(){
chatroomRef.off("child_added");
}
I'm well impressed with what you've done here :)
ReplyDeleteHave to try to find the time to give it a go myself
Ian
Hi,
ReplyDeleteI would like to implement chat capability in my AC app.
Do you have example of what you've done ?
Thanks
Sylvain
Hi,
ReplyDeleteYou can check out the app that goes with the example code here -- http://acft.ws/mghw.
HTH,
A.