2017년 5월 17일 수요일

Firebase Chat with Interactive Drawing


AppyBuilder.com includes a component called FirebaseDB which provides a way to use cloud data in Android apps that you invent. The data is stored and maintained using Firebase database service (http://www.firebase.com), which is part of Google. A powerful feature of Firebase database is that data will be synchronized, in realtime, to every connected client. This means that if user1 stores a piece of data in the cloud, all connected clients will automatically be notified of the data change.
In this post, I’ll discuss how to develop a chat application, along with an interactive drawing app. The application will allow all connected users to chat with each. In addition, if any user draws on the app canvas, it will let all other user to view drawing, in realtime, as its being drawn! The final application will look like below showing two users chatting and playing the popular XOXO game.


Starting

This app, will have the graphics layout shown above and will include realtime chat and interactive drawing capability where user’s will be able to chat and view each-other’s drawing in real-time!
We’ll start by creating a new project and we’ll call it PaintPotVIII (for Part III). If you like to test the app, you can jump to bottom of this post and scan the QR code to install the app onto your device.

Designer Editor

We will implement ability to record the name of the last person sending chat message or performing drawing. For this, we’ll use the following components:
ComponentName itDescription
HorizontalArrangementHorizontalArrangement1Length: Fill Parent
Container for below components
 LabelLabel1Font: Bold
Text: *Your Name:
 TextBoxtxtNameLength: Fill Parent



Next, we’ll add a component to show chat history:
ComponentName itDescription
TextBoxtxtChatHistoryLength: Fill Parent
Height: 66DPs
Multiline
Clear text

Next, we will add components for typing a chat message for sending it to connected users:
ComponentName itDescription
HorizontalArrangementHorizontalArrangement2Length: Fill Parent
Container for below components
 ButtonbtnSendMsgText: Send
 TextBoxtxtChatMsgLength: Fill Parent
Clear text
 ButtonbtnClearHistoryText: Clear History

Next, we will add a Canvas with a background picture, used for interactive drawing:
ComponentName itDescription
CanvasCanvas1Length: Fill Parent
Height: 300DPs
LineWidth: 5.0
Background Image kitty.png

Next, we need to add in a Label. This label will be used to show the current user’s name, if any, who is drawing. The name will be populated from txtName of the client whom is drawing on the canvas. This will be covered in detail in the blocks editor.
ComponentName itDescription
LabellblNowDrawingText: Last by:
HorizontalArrangementdefaultLength: Fill parent
Container for below components
ButtonbtnWipeText: Wipe
ButtonbtnRedText: Red
BackgroundColor: red
TextColor: White
ButtonbtnBueText: Blue
BackgroundColor: blue
TextColor: White
ButtonbtnBlackText: Black
BackgroundColor: black
TextColor: White
Final part on the Design Editor is to add a FirebaseDB component. This is a non-visible component that will be used to store and read data from could. For time being, leave all properties as default. For information about Firebase, please visit http://firebase.com
At this time, your layout, should look like image below.

Blocks Editor

Think of FirebaseDB as datastorage with functionality like TinyWebDb, where you can store key, value pairs. For this, we declare and use five global variables as shown below.
  • KEY_LINE variable will be used as key for storing and retrieving data-points for drawing lines
  • KEY_USER will be used as key for persisting/retrieving last user name
  • KEY_COMMAND will be used for determining the pen color (for drawing on canvas)
  • KEY_CHAT will be used for persisting/retrieving chat messages
  • csvList will be a list variable for parsing data that is retrieved from our FirebaseDB

When drawing on canvas or when tapping any of our color buttons, we need to check if user has entered name. If so, we store user’s name in FirebaseDB in cloud. To avoid redundant coding, we define a Procedure and reuse this procedure from different event handler blocks. For this, we declare a Procedure named “validateNameAndStoreName”. It basically checks to see if user has entered a value in txtName textbox. If true, then we use use our KEY_USER variable to store user name into our FirebaseDB. If no name entered, then no action will be taken.

When user taps on “Clear Chat History”, we need to clear its related textbox. Below are the blocks for this action:

Tapping on btnRed, btnBlue, btnBlack buttons should change the canvas pen color on our device AND also on ALL the connected devices. Blocks below shows that when button is clicked, we 1st, call our procedure validateNameAndStoreName procedure (see above). If you recall, that procedures checks to see if user has entered name and if so, it stores name into FirebaseDB. Next, based on clicked-button, we change the canvas paint color. Next, we store COLOR_RED (or black or blue) with a key of KEY_COMMAND into our database. These blocks will change the canvas paint color on user’s device and I’ll later cover how we change the paint color on ALL other connected devices.

Tapping on btnWipe should clear the canvas on our device and all other connected devices. Below are the blocks for this. The procedure checks to see if user has entered name, if so, it sends the user’s name to FirebaseDB. Next we clear the canvas. Then we store a value “ERASE” with key of KEY_COMMAND into FirebaseDB. We use KEY_COMMAND key as a generic tag (key) for storing color (above) or actions like ERASE (clearing canvas). More on this later.

Next, I’ll cover how to draw on our canvas. When dragging finger on canvas, Canvas.Dragged event handler will be triggered. For this, we need to draw lines on our canvas, send our name to FirebaseDB and also store the x,y coordinates to FirebaseDB. For this, we call our validateNameAndStoreName to save name to database. Next, draw line on our canvas using Canvas.DrawLine. Next, we need to store prevX, PrevY, currentX, currentY to our database. We will store then in a CSV format as shown below using the join block and store into FirebaseDB using a key of KEY_LINE.

Next, we’ll cover on sending chat messages. User can type a message in txtChatMsg textbox and tap the button to send the message. For this we perform a basic validation to ensure if any text has been entered or not. If no text entered, we don’t do anything. However, if text is entered, we send user’s name (using validateNameAndStoreName) to database. We also use our global variable KEY_CHAT to store chat message. Before sending the chat message, we take user’s name for txtName, join with colon (:) followed by chat message. Lastly, we clear the txtChatMsg. We are using a Procedure to accomplish this, but, for this, you could eliminate the procedure and pull all blocks into btnSendChat event handler.

Up to this point, I have shown you how to draw lines or change color on your own device and also how to store data into cloud FirebaseDB. However, this is an interactive app and any drawing or chat messages, should be drawn on all other connected devices and messages should also be send to all other devices.
FirebaseDB component has an event-handler block called DataChanged. Firebase sends notification to all other connected devices (for the same app) whenever its data is updated, deleted or inserted. For example, let’s say we execute FirebaseDB.StoreValue with key of KEY_USER and value of John. Once this value gets stored, FirebaseDB triggers DataChanged on every connected device that is running the same app.
FireBaseDB.DataChanged event handler sends two parameters as follows:
  • tag: this is the name of the tag or the key for which data has been updated
  • value: this is the value for tag
When this event is triggered, we check to see which piece of data has been changed. If you recall, when drawing on canvas, we stored prevX, prevY, currentX, currentY in CSV format with a key of KEY_LINE.
The if block below, checks to see if the reported tag (key) is KEY_LINE. If yes, this means user another user is drawing on canvas. We get the CSV value, convert the CSV into a list using “list from csv row” and store it into our global csvList variable. Next, we simply take each piece of data and use it to draw lines on the canvas.
If the tag (key) is KEY_USER, it means data has been updated in cloud. We get the associated value and update our lblNowDraing text to show its related value (last user’s name).
If the tag (key) is KEY_CHAT, it means someone has sent in chat message. For this, we basically take value and join it with an empty line (\n) and join it with existing txtChatHistory textory message. We then store the result back into txtChatHistory textbox.
If the tag (key) is KEY_COMMAND, we call a stored procedure, called parseCommand, to inspect the command. We are using a procedure to reduce the number of blocks in our DataChanged event handler

The procedure parseCommandBelow is called from above blocks. It basically checks to see what command was sent to FirebaseDB. If the command was ERASE, we use Canvas.Clear to clear canvas. If command was COLOR_RED, we change paint color. We do same for COLOR_BLUE and COLOR_BLACK

The ultimate result is an interactive drawing app with chat feature where in realtime drawings on any user’s device will, in real-time, be shown on other connected devices that run the same app

Challenge:

You can challenge yourself by extending this app’s feature to draw circles when canvas is touched. Another challenge would be to make the kitty meow when a button (e.g. Pet Me) is tapped.

Code:

  • .apk – Click HERE to get the .apk to test on the app on your device.
  • .aia – Please note that there are 2 versions of this app:
    • A version that was developed using AppyBuilder. This version includes all features that you see in this tutorial. Get it HERE
    •  A version that was developed using MIT AI. This version, currently, does not include the chat feature and will soon be coming. Get it HERE

Comments / questions?

We love to hear from you. Use below to provide feedback. Like this tutorial? Please tweet or give us thumbs-up :o)

Interested about AppyBuilder?

If you like to checkout AppyBuilder, please see our membership plans  HERE.

댓글 없음:

댓글 쓰기