# 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:

**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.