# Unit 5 Lab Exercises ### Challenge There will be about 90 minutes allotted for this lab. The goal of this lab is to build a chat application using Parse as a back-end. You'll mostly be building the chat application and leveraging an existing Parse server. For more context, checkout the [lab overview video](https://youtu.be/nA8qe-Nb0t0). For a step-by-step guide for this challenge, check out the [building a chat client](http://guides.codepath.org/android/Building-Simple-Chat-Client-with-Parse) cliffnotes. Below is the final output: ![Chat App|250](https://i.imgur.com/v8R5LyU.png =300x) **Reminders for this challenge:** * Double-check that the correct parse keys are properly specified within the `Parse` initialize call * Make sure you are creating a `ChatApplication` and registering it in the `<application>` node in `AndroidManifest.xml` * Check that your emulator / device has access to internet if things aren't working * Follow the [Parse Chat guide](http://guides.codepath.org/android/Building-Simple-Chat-Client-with-Parse) but don't just copy the code **Goal:** Pair up and build a simple chat client where you can post messages and receive messages using Parse. 1. Review the lab overview video * Watch our [quick 5-min lab intro](https://youtu.be/nA8qe-Nb0t0) for an overview of what we are building in this lab. 2. Setup Parse server * Parse is an **open-source node.js project** that exposes an easy-to-use database / API which can be used to develop mobile applications. Parse uses MongoDB and mobile SDKs to allow data to be stored and retrieved by a mobile app from a server-side back-end without requiring any special server code to be written by the mobile developer. * You can choose either of the following options to get a Parse Developer Account: * [**OPTION 1 - No Action Required**] In this lab, we'll be sharing a Parse Developer Account that has already been created by us. To use this account, the `applicationId` and `server` are provided in step 3 below. * [**OPTION 2**] Alternatively, you can [setup your own Parse server](http://guides.codepath.org/android/Configuring-a-Parse-Server) pointing the client to your own self-hosted URL. Please note that if you decide to create your own instance of the Parse server, you will have to use [Back4App](https://back4app.com) or similar solution. 3. Generate an Android project in Android Studio * Create a new Android project (minSDK 18) and call it `SimpleChat`. * Add an **Empty `Activity`** named `ChatActivity` and create the project. 4. Setup Parse * If you are using our shared Parse account, use the following credentials: * `applicationId`: `IT9CFEu9H3rj1FHLMckJVUfExqCKZ3k4CWzpCj6L` * `clientKey` : `tWEHG16AVN7KpuePR9NCjf7lLTzItE7DUmFeaLvB` * `server` : `https://parseapi.back4app.com` * Follow [Setup Parse client section](http://guides.codepath.org/android/Building-Simple-Chat-Client-with-Parse#2-setup-parse-client) of the Parse guide to create and setup your project. Replace the `YOUR_APPLICATION_ID_HERE` and `YOUR_CLIENT_KEY` with the correct values. Use the above `applicationId` and `server` if you are using the shared Parse Developer Account created by us. ```java Parse.initialize(new Parse.Configuration.Builder(this) .applicationId("YOUR_APPLICATION_ID_HERE") .clientKey("YOUR_CLIENT_KEY") .server("https://parseapi.back4app.com") .addNetworkInterceptor(new ParseLogInterceptor()).build()); ``` * Make sure to add the fully qualified name of your `Application` subclass (i.e `ChatApplication`) to the `<application>` tag in your `AndroidManifest.xml`: `android:name="com.codepath.simplechat.ChatApplication"`. 5. Design Layout * The goal is to design your fundamental blocks for the simple chat application. * Open your layout file `activity_chat.xml`, add an `EditText` and a `Button` to compose and send text messages. 6. Login with anonymous parse user * We will register and login as an [anonymous user](http://parseplatform.org/docs/android/guide/#anonymous-users) on each device to log into our simple chat app. * Hint: The easiest way to get the logged in user is described in this [current user](http://parseplatform.org/docs/android/guide/#current-user) section. 7. Save Messages * On click of 'Send' button, save the message object to Parse. This is done by constructing a new `ParseObject` and then calling `saveInBackground()` to persist data to the database. * You can choose to toast a message on save. * Hint: See this guide on [saving objects](https://docs.parseplatform.org/android/guide/#saving-objects) in parse. 8. Verify Save * Run your application and try to send a text to parse. If the save was successful, you should see 'Successfully sent message to parse.' toast on your screen. * [**OPTION 1**] Follow this step if you are using the Shared Parse Account. * To make sure the data was saved, verify that your message appears in the app projected by your facilitator. * [**OPTION 2**] Follow this step if you are using your personal Back4App account. * To make sure the data was saved, you can verify whether the objects were created by clicking on the `Core --> Database browser` tab in your Back4App project Dashboard. Refer [testing parse deployment guide](http://guides.codepath.org/android/Configuring-a-Parse-Server#testing-deployment) for more info. 9. **(Bonus)** Retrieve Messages: Build UI * Now that we have verified that messages are successfully being saved to your parse database, lets go ahead and build the UI to retrieve these messages. Open your layout file `activity_chat.xml`and add a `RecyclerView` to display text messages from parse. * Create layout files for different message types (incoming and outgoing). Name them `message_incoming.xml` & `message_outgoing.xml`, design the layouts by adding a `TextView`s and an optional `ImageView` to display profile picture. * Experiment with creating background to display message "bubbles". 10. **(Bonus)** Retrieve Messages: Data Binding * Create `Message.java` model class to provide data to `RecyclerView`. * Create custom list adapter `ChatListAdapter.java` and pass `Message`s there. * Define different view types for messages and create custom `ViewHolder`s for each type. * Implement `bind()` functions to assign values based on message type. * Fetch the saved messages to load the `RecyclerView` using `ParseQuery`. * Hint: Refer this guide on [retrieving objects](https://docs.parseplatform.org/android/guide/#retrieving-objects) from parse and [querying your results](https://docs.parseplatform.org/android/guide/#queries). 11. **(Bonus)** Refresh Messages * Refresh the `RecyclerView` with latest messages [using a handler](http://guides.codepath.org/android/Repeating-Periodic-Tasks#handler). The handler will call a runnable to fetch new messages every few seconds. * Only start the handler task when activity is active and stop it when activity goes into background. * Note: Executing a runnable every few seconds will refresh your list every few seconds interrupting any scroll events. If you want to be able to scroll your messages, consider setting the appropriate [transcriptMode for the list](http://developer.android.com/reference/android/widget/AbsListView.html#attr_android:transcriptMode) using [setTranscriptMode()](http://developer.android.com/reference/android/widget/AbsListView.html#setTranscriptMode(int)) method. Next, you'll have to manually scroll to the bottom of the list on the first load. 12. **(Bonus)** [Refresh Messages with Live Queries](http://guides.codepath.org/android/Building-Simple-Chat-Client-with-Parse#13-live-queries) * Replace periodic refreshing by using Parse Live Queries. 13. Run and test your app to verify correct behavior with your functioning chat client. ### Concept Review * What is the main thread or UI thread? Why can't we block it? * What is the easiest way to execute background tasks? * What types do an AsyncTask accept when being defined? * How would I load a remote image without using any third-party libraries? * What are the major four methods for persistence? * What is the equivalent of cookies in Android? * How do you work with SQL without the use of an ORM? Describe working with SQLiteOpenHelper. * What is an ORM? How does using an ORM work? ### Additional Optional Exercises There are a series of exercises you **optionally** can perform to **review the concepts** introduced this week: * [Chapter 6: Networking Exercises](http://codepath.github.io/intro_android_exercises/chapters/chapter06.html) * [Chapter 8: Persistence Exercises](http://codepath.github.io/intro_android_exercises/chapters/chapter08.html) These are in addition to the mini-projects and are not required but are supplemental content.