# Overview

## Introduction

Chat21 is a multi platform SDK that adds Instant Messaging to your iOS, Android and Web applications.

IOS and Android SDKs provide you methods to initialize and configure chat features embedded in your own mobile app. Chat21 SDKs helps you to build a standalone chat application as well. The SDKs provide ready to use UI components and *extension points* for embedding and customizing a chat into your app. Chat21 uses [Firebase](http://firebase.google.com) platform as backend.

Please choose a platform to start:

## iOS

[Get started tutorial](/ios/get-started)

[APIs](https://github.com/chat21/chat21-docs/tree/8ab923d159962acfcaf604579422dfbfd81c7689/ios/api/README.md)

## Android

[Get started tutorial](/android/get-started-for-android)


# Get Started for iOS

Create a fully functional chat as a Single View Application

## Introduction

With this tutorial you will learn how to create a fully functional chat as a **Single View Application** in *Swift* or *Objective-c* using XCode.

The full code of this tutorial is available on GitHub:

[DOWNLOAD SWIFT SOURCE CODE](https://github.com/chat21/chat21-get-started-swift)

[DOWNLOAD OBJECTIVE-C SOURCE CODE](https://github.com/chat21/chat21-get-started-ios)

## Prerequisites

Before you begin, you first need to set up your environment:

1. Xcode 9.0 or later
2. An Xcode project targeting iOS 9 or above
3. The bundle identifier of your app

## Firebase setup

### **Create a Firebase project**

Sign up on Firebase and create a project. Please refer directly to Firebase [https://firebase.google.com](https://firebase.google.com/) to accomplish and better understand this task. Chat21 relies on Firebase as the backend, so it's really important for you to acquire familiarity with Firebase and all of his services.

### Setup the backend for your project

After you successfully created a Firebase project you must **setup the backend**. Please follow this link to install [**Chat21 cloud functions**](https://github.com/chat21/chat21-cloud-functions) on your just created Firebase project.

## Configure authentication

Now with the setup of your Firebase project and backend functions installed you can enable email authentication to provide an easy way for your app to sign in with email and password.

Enable **email signin** in Firebase console:

![](http://www.chat21.org/wp-content/uploads/2018/02/firebase-add-user-step0-1500x746.png)

Create a user to test chat functions:

![](http://www.chat21.org/wp-content/uploads/2018/02/firebase-add-user-step1-1500x692.png)

Choose email and password:

![](http://www.chat21.org/wp-content/uploads/2018/02/firebase-add-user-step2-1500x692.png)

Add the user with “ADD USER” button.

## Create the Xcode project

This tutorial will focus on the creation of a simple **single view application**. In the next tutorial you will approach the creation of a more realistic **multi tab application** (similar to Whatsapp).

First open Xcode, select File > New > Project and choose Single View App:

![](http://www.chat21.org/wp-content/uploads/2018/02/xcode-create-project-step1-1030x742.png)

Insert the project info using **MyChat** as project name and insert your team: &#x20;

![](/files/-Li9uqpKnaI5M15lZtcz)

## Create the Firebase iOS App

Switch on the project on Firebase, go to the *Firebase Console* > *Project Overview* and add a **iOS App** to your project by clicking on “Add iOS App” and follow the setup steps.

When prompted, enter your app’s bundle ID. It’s important to enter the bundle ID your app is using, this can only be set when you add an app to your Firebase project.

At the end, you’ll download a **GoogleService-Info.plist** file. You can download this file again at any time.

Now add this file to your Xcode project root using the Add Files utility in Xcode (from the File menu, click Add Files). Make sure the file is included in your app’s build target.

## Add Chat21 SDK to the project

Chat21 uses CocoaPods so simply create a file named “Podfile” in the project’s root folder with the following content:

```
platform :ios, '10.0'
use_frameworks!

target 'MyChat' do
  pod 'Chat21'
end

```

**Close Xcode** and run:

> **pod install**

From now on open the project using *MyChat.xcworkspace* file.

## Get started with the UI

Open **AppDelegate.m** adding the following import directives:

{% tabs %}
{% tab title="Swift" %}

```swift
import Firebase
import Chat21
```

{% endtab %}

{% tab title="Objective-c" %}

```objectivec
#import "AppDelegate.h"
#import "ChatManager.h"
#import "ChatUIManager.h"
#import "ChatUser.h"
#import "ChatAuth.h"
@import Firebase;
```

{% endtab %}
{% endtabs %}

Now configure Firebase and Chat frameworks. Edit the **didFinishLaunchingWithOptions** method, adding the following code:

{% tabs %}
{% tab title="Swift" %}

```swift
FirebaseApp.configure()
ChatManager.configure()
let email = "YOUR EMAIL";
let password = "YOUR PASSWORD";
ChatAuth.auth(withEmail: email, password: password) { (user, error) in
    if let err = error {
        print("Authentication error: ", err.localizedDescription);
    }
    else {
        let chatm = ChatManager.getInstance()
        if let user = user {
            user.firstname = "YOUR FIRST NAME";
            user.lastname = "YOUR LAST NAME";
            chatm?.start(with: user)
            let conversationsVC = ChatUIManager.getInstance().getConversationsViewController()
            if let window = self.window {
                window.rootViewController = conversationsVC
            }
            chatm?.createContact(for: user, withCompletionBlock: { (error) in
                print("Contact successfully created.")
            })
        }
    }
}
return true
```

{% endtab %}

{% tab title="Objective-c" %}

```objectivec
[FIRApp configure];
[ChatManager configure];

NSString *email = @"YOUR-EMAIL";
NSString *password = @"YOUR-PASSWORD";
[ChatAuth authWithEmail:email password:password completion:^(ChatUser *user, NSError *error) {
  if (error) {
    NSLog(@"Authentication error. %@", error);
  }
  else {
    ChatManager *chatm = [ChatManager getInstance];
    user.firstname = @"YOUR FIRST NAME";
    user.lastname = @"YOUR LAST NAME";
    [chatm startWithUser:user];
    UINavigationController *conversationsVC = [[ChatUIManager getInstance] getConversationsViewController];
    self.window.rootViewController = conversationsVC;
    [[ChatManager getInstance] createContactFor:user withCompletionBlock:nil];
  }
}];
```

{% endtab %}
{% endtabs %}

Using the previously created user’s email and password, add this code to the **didFinishLaunchingWithOptions** method:

Now **launch** the project.

If everything is correct you will see the conversations’ history with no conversations.

![](http://www.chat21.org/wp-content/uploads/2018/02/app-view-conversations-2.png)

As you can see, in the **authWithEmail** completion block we use the *createContactFor* method to create a contact on the remote backend for the currently signed user. In this way every user will add his metadata to contacts as soon as he signs in. The button on the upper right corner opens the contacts list.

![](http://www.chat21.org/wp-content/uploads/2018/02/app-view-select-contact-2.png)

You will see yourself listed. If you want you can chat with yourself but it’s better to create another user and sign in on a chat installed on another device (or simulator instance).

Happy chatting 🙂

Feel free to send feedbacks to <support@frontiere21.it>


# Authentication

## Introduction

Chat21 uses Firebase as backend (a Chat21 standalone engine is under development), and because of this dependency Chat21 actually relies on Firebase for authentication and users' management.

All of these examples are available in the **Chat21 Swift Playground** project 👉🏻 <https://github.com/chat21/chat21-swift-playground>. We strongly recommend you to install and configure the playground and use it to try all of these examples.

If you have feedbacks or suggestions about this documentation, please send us an email at **<support@frontiere21.it>**. We are always open to improvements coming from Chat21 Community!

## Register a new user

To register a new user using email and password you can use directly Chat21 **ChatAuth** class method *createUser*, like in the example below:

```swift
let email = "MY EMAIL"; /** FIREBASE USER EMAIL **/
let password = "MY PASSWORD"; /** FIREBASE USER PASSWORD **/
ChatAuth.createUser(withEmail: email, password: password) { (user, error) in
    if let user = user {
        user.firstname = "FIRST NAME";
        user.lastname = "LAST NAME";
        let chatm = ChatManager.getInstance()
        // always save the new user as a contact in remote contacts DB
        chatm?.createContact(for: user, withCompletionBlock: { (error) in
            print("Contact successfully created.")
            // then initialize chat with the just created user
            chatm?.start(with: user)
        })
    }
}
```

As soon as you create a user you should save the newly created one in Contacts with **ChatUser.createContact** method. In this manner his *first name* and *last name* become persistent in the cloud of Chat21 and will be available to everyone will connect to your chat.

## Sign in with existing user

To sign in with an existing user you can use **ChatAuth.auth** method:

```swift
let email = "MY EMAIL"; /** FIREBASE USER EMAIL **/
let password = "MY PASSWORD"; /** FIREBASE USER PASSWORD **/
ChatAuth.auth(withEmail: email, password: password) { (user, error) in
    if let err = error {
        print("Authentication error: ", err.localizedDescription);
    }
    else {
        if let user = user {
            user.firstname = "FIRST NAME";
            user.lastname = "LAST NAME";
            let chatm = ChatManager.getInstance()
            chatm?.start(with: user)
            chatm?.createContact(for: user, withCompletionBlock: { (error) in
                print("Contact successfully created.")
            })
        }
    }
}
```

Every time you sign in with a user remember to instantiate a Chat with that user with **ChatManager.start** method:

```swift
let chatm = ChatManager.getInstance()
chatm?.start(with: user)
```

## Sign in with Firebase

If you prefer you can sign in directly using Firebase users (for example, if you already use Firebase for your App). Simply remember to create a ChatUser with the Firebase UserId and then start the chat, as in the example below:

```swift
let email = "andrea@email.it"; /** FIREBASE USER EMAIL **/
let password = "123456"; /** FIREBASE USER PASSWORD **/
Auth.auth().signIn(withEmail: email, password: password) { (result, error) in
    if let error = error {
        print("Error while authenticating: \(error)")
    }
    else if let result = result {
        let firebase_user: User = result.user
        let user: ChatUser = ChatUser()
        user.userId = firebase_user.uid
        user.email = email
        user.firstname = "John";
        user.lastname = "Nash";
        let chatm = ChatManager.getInstance()
        chatm?.start(with: user)
        chatm?.createContact(for: user, withCompletionBlock: { (error) in
            print("Contact successfully created.")
        })
    }
}
```

## Custom authentication

If your app already has his own user base and you just want to add chat features to let users talk with each other the best way is to use **custom authentication**.

Custom authentication directly relies on Firebase. You must read Firebase documentation available here:

<https://firebase.google.com/docs/auth/admin/create-custom-tokens>

After you'll login with Firebase Custom Auth you will have to create a ChatUser using the **Firebase UserId** as in the examples before, then you can start the chat with the **ChatManager.start** method.<br>


# User Interface

## Introduction

Chat21 provides many ready-to-use UI components. Beyond these components Chat21 has some extension points that allows a developer to plug his own custom components for improving or customizing chat's default behaviour.

All of these examples are available in the **Chat21 Swift Playground** project 👉🏻 <https://github.com/chat21/chat21-swift-playground>. We strongly recommend you to install and configure the playground and use it to try all these examples.

If you have feedbacks or suggestions about this documentation, please send us an email at **<support@frontiere21.it>**. We are always open to improvements coming from Chat21 Community!

## Open Conversations View

The first view that a user expects in a chat is the list of his recent conversations. Chat21 provides this feature with the **ChatUIManager.openConversations** method:

```
ChatUIManager.getInstance()?
    .openConversationsView(
        asModal: self,
        withCompletionBlock: nil)
```

## Open a Messaging view with someone

If you want to place a button around your app to allow the *signed* user to select a contact from available contacts and open a conversation with him you can use **ChatUIManager.openSelectContactView** method. This method opens a modal dialog that allows the selection of a user among those already registered in the App:

```
ChatUIManager.getInstance()?.openSelectContactView(asModal: self, withCompletionBlock: { (contact, canceled) in
    if (canceled) {
        print("canceled")
    }
    else {
        ChatUIManager.getInstance()?
            .openConversationMessagesViewAsModal(
                with: contact,
                viewController: self, 
                withCompletionBlock: { () in
                    print("Messages view dismissed.");
                });
    }
})
```

As you can see, as soon as a contact is selected, the completion block is called with the contact parameter populated (type ChatUser). This contact is then passed as a parameter to **ChatUIManager.openConversationMessagesViewAsModal**. This last method opens a dialog to instant messaging with the target user.

The decoupling of the Contact Selection view from the Contact Messaging view allows for an easy plug of alternative Contact Selection components, allowing a developer to choose contacts from alternative contacts DBs (different from Chat21 native contact management).

## Messaging without Contact Selection view

Design requirements often opt to place a button inside the Profile View of a user to directly message with him. If you want to bypass contact selection view and message to a user directly, i.e. tapping a button on UI, just like you message to a user from his Instagram Profile, you need to create a ChatUser instance with the following **minimum** properties set:

* ChatUser.userId
* ChatUser.firstname
* ChatUser.lastname

Please notice that while *userId* must correspond to a valid Firebase user, *firstname* and *lastname* are totally arbitrary. You must provide this two properties from your user database or from Chat21 Contact Management.

In this example a contact is created with the minimal information to start a conversation:

```
let contact: ChatUser = ChatUser()
contact.userId = "5aaa99024c3b110014b478f0"; // valid Firebase uid
contact.firstname = "Andrew";
contact.lastname = "Leo";
ChatUIManager.getInstance()?.openConversationMessagesViewAsModal(with: contact, viewController: self, withCompletionBlock: { () in
    print("Messages view dismissed.");
});
```

{% hint style="info" %}
Every contact you want to open a conversation with must be an already registered Firebase user (with a valid Firebase userId).
{% endhint %}

## Embed View components

Sometimes you just need the raw UI Component just to embed the Component itself into another View (i.e. a tab in Tabbed Application). To access the raw components you can use the **getCOMPONENT-NAMEComponent()** methods of the **ChatUIManager** class. Here follows some code snippet to get the main components of the Chat21 framework

```
let vc: UINavigationController? = 
            ChatUIManager.getInstance()?
            .getConversationsViewController()
```

```
let vc: UINavigationController? = 
            ChatUIManager.getInstance()?
            .getSelectContactViewController()
```

```
let vc: UINavigationController? = 
            ChatUIManager.getInstance()?
            .getMessagesViewController()
```

```
let vc: UINavigationController? = 
            ChatUIManager.getInstance()?
            .getSelectGroupViewController()
```

## Pluggable User Interface components

### Plug User Profile View

Chat21 APIs does not provide a "Profile view" because it is generally provided by the Host application, showing User info relative to the same App.

Chat21 provides instead an easy way to plug in the profile view of your Application in all the UI points where this view is invoked. Simply use the **ChatUIManager.pushProfileCallback** callback to plug your external view. Here follows an example:

```
ChatUIManager.getInstance()?.pushProfileCallback = { (user, vc) in
    let storyboard: UIStoryboard  = UIStoryboard.init(name: "Main", bundle: nil);
    let profileVC: ProfileViewController = storyboard.instantiateViewController(withIdentifier: "user-profile-vc") as! ProfileViewController    
    profileVC.user = user // Pass the chatUser to the view to get info on the user
    vc?.navigationController?.pushViewController(profileVC, animated: true)
}
```

In the previous example a "profile view" is created using a View Controller in *Main.storyboard*. The **ProfileViewController.user** parameter is used to get info about the current user showing his informations.

### Plug your own Select Contact View

While Chat21 has its own Contact management component sometimes you probably want to have your own source of contacts. Chat21 provides you the option to plug your own Contact Selection View.

This view is activated every time a user taps on the "write to" button, on the top right of conversations summary (generally the main view).

![Native "Write to" button](/files/-LsvYq33PoUDfO2JwlVI)

Your custom view must simply conform to [**ChatSelectContactProtocol**](https://github.com/chat21/ios-sdk/blob/master/Chat21/Chat21UI/view/ChatSelectContactProtocol.h). You can find an instance of a custom contact selector 👉🏻 [MySelectContactViewController](https://github.com/chat21/chat21-swift-playground/blob/master/MyChat/MySelectContactViewController.swift) in the [Swift Playground](https://github.com/chat21/chat21-swift-playground) project.

Once you write in your own class you can simply plug it in your project with the following lines:

```
let storyboard: UIStoryboard  = UIStoryboard.init(name: "Main", bundle: nil);
let select_user_vc: MySelectContactViewController = storyboard.instantiateViewController(withIdentifier: "select-user-vc") as! MySelectContactViewController
ChatUIManager.getInstance()?.selectUserViewController = select_user_vc;
```

As you can see from sources this view simply reply with a callback containing the selected contact (type: ChatUser) as parameter.


# Get Started for Android

Your first Android App with Chat21 SDK

## Introduction

With this tutorial you will learn how to create a fully functional chat as a Single View Application.

The full code of this tutorial is available on GitHub:

[DOWNLOAD SOURCE CODE](https://github.com/chat21/chat21-get-started-android)

## Prerequisites

Before you begin, you need a few things to set up in your environment:

* Android Studio 3.0.0 or later
* Android SDK Build-Tools 26.0.2 or later
* A Firebase project correctly configured and the Chat21 Firebase cloud functions installed. Detailed instructions [here](https://github.com/chat21/chat21-cloud-functions)

## Firebase setup

### **Create a Firebase project**

Sign up on Firebase and create a project. Please refer directly to Firebase [https://firebase.google.com](https://firebase.google.com/) to accomplish and better understand this task. Chat21 relies on Firebase as the backend, so it's really important for you to acquire familiarity with Firebase and all of his services.

### Setup the backend for your project

After you successfully created a Firebase project you must **setup the backend**. Please follow this link to install [**Chat21 cloud functions**](https://github.com/chat21/chat21-cloud-functions) on your just created Firebase project.

## Configure authentication

Now with the setup of your Firebase project and backend functions installed you can enable email authentication to provide an easy way for your app to sign in with email and password.

Enable **email signin** in Firebase console:

![](/files/-LsSa74n9mdXf4bBngEd)

Create a user to test chat functions:

![](/files/-LsSbDRSj8QR25lEiyOm)

Choose email and password:

![](/files/-LsSbNDey3DSCSHo5VQQ)

Add the user with “ADD USER” button.

## Create Android Studio project

This tutorial will focus on the creation of a simple **single view application**. In the next tutorial you will approach the creation of a more realistic **multi tab application** (similar to Whatsapp).

First open Android Studio, select Start a new Android Studio Project and insert the project info using **MyChat** as project name and insert your team.

**NOTE: Take note of the Package name, it will be used in the following steps**

![](/files/-LsSboG9viodyvNLY7sf)

Select the Phone and Tablet > API Android 19: 4.4 (Kitkat) as minimum SDK

Select Empty Activity

![](/files/-LsScWMYnx0WZiK0gZ1S)

Insert the Activity and the Layout name

![](/files/-LsScbdzJlWLJZpMb15l)

## Create the Firebase Android App

Switch on the project on Firebase, go to the *Firebase Console* > *Project Overview* and add a **Android App** to your project by clicking on “Add Android App” and follow the setup steps.

When prompted, enter your app’s Package name (you have pinned previously). It’s important to enter the Package name your app is using, this can only be set when you add an app to your Firebase project.

At the end, you’ll download a **google-services.json** file. You can download this file again at any time.

Now add this file to your Android project App root

![](/files/-LsSdyRK_BknmSz5iQ-d)

## Add Firebase libs to the project

Now go back to your Android project and add firebase libraries to your project.

First, add rules to your **root-level** `build.gradle` file, to include the google-services plugin and the Google’s Maven repository:

```
buildscript {
    // ...
    dependencies {
        // ...
        classpath 'com.google.gms:google-services:4.2.0'
    }
}

allprojects {
    // ...
    repositories {
        // ...
        google()
    }
}
```

Then, in your **module** Gradle file (usually the `app/build.gradle`), add the `apply plugin` line at the bottom of the file to enable the Gradle plugin:

```
apply plugin: 'com.android.application'
// ...
dependencies {
    // ...
    implementation "com.google.android.gms:play-services:11.8.0"
}
// ... 
apply plugin: 'com.google.gms.google-services'
```

NOTE: the complete guide to add Firebase libs to you project is available here: <https://firebase.google.com/docs/android/setup>

## **Install Chat21 libraries**

Add the following to your `app/build.gradle` file:

```
defaultConfig {
// ...
multiDexEnabled true
}
dependencies {
// ...
implementation 'com.android.support:multidex:1.0.1'
implementation "com.google.android.gms:play-services:11.8.0"
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'org.chat21.android:chat21:1.0.15'
implementation 'com.vanniktech:emoji-ios:0.5.1'
implementation 'com.github.bumptech.glide:glide:3.7.0'
implementation 'com.daimajia.swipelayout:library:1.2.0@aar'
}
// ...
configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        def requested = details.requested
        if (requested.group == 'com.android.support') {
            if (!requested.name.startsWith("multidex")) {
                details.useVersion '26.1.0'
            }
        }
    }
}
```

Create a custom Application class

```
public class AppContext extends Application {

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
           MultiDex.install(this); // add this
    }
}
```

and add it to the Manifest.xml

```
<application
             android:name=".AppContext"
             android:icon="@mipmap/ic_launcher"
             android:label="@string/app_name"
             android:theme="@style/AppTheme"
             ...
</application>
```

#### **Style**

Replace the default parent theme in your **styles.xml**

“Theme.AppCompat.Light.~~**DarkActionBar”**~~ with Theme.AppCompat.Light. **NoActionBar**

```
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
   <!-- Customize your theme here. -->
   <item name="colorPrimary">@color/colorPrimary</item>
   <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
   <item name="colorAccent">@color/colorAccent</item>
</style>
```

**Get start with the UI**

Add the following code to the **onCreate** method of your Main Activity and substitute variable in bracket using the previously created user’s email and password. For **APP\_ID** use "chat" (this is the tenant's name and MUST be the same for all of your Clients, ex. iOS)

```
FirebaseDatabase.getInstance().setPersistenceEnabled(true);

ChatManager.startWithEmailAndPassword(this, [APP_ID], 
  [YOUR_EMAIL], [YOUR_PASSWORD], new ChatAuthentication.OnChatLoginCallback() {
   @Override
   public void onChatLoginSuccess(IChatUser currentUser) {
      ChatManager.getInstance().createContactFor(currentUser.getId(), currentUser.getEmail(),
          [YOUR_FIRST_NAME], [YOUR_LAST_NAME], new OnContactCreatedCallback() {
              @Override
              public void onContactCreatedSuccess(ChatRuntimeException exception) {
                  if (exception == null) {
                      ChatUI.getInstance().openConversationsListActivity();
                  } else {
                      // TODO: handle the exception
                  }
              }
          });
   }

   @Override
   public void onChatLoginError(Exception e) {
          // TODO: 22/02/18
   }
});
```

Now **launch** the project.

If everything is correct you will see the conversations’ history with no conversations.

![](/files/-LsSjGWW_tJw5jEaO16o)

As you can see, in the **authWithEmail** completion block we use the *createContactFor* method to create a contact on the remote backend for the currently signed user. In this way every user will add his metadata to contacts as soon as he sign in. The button on the bottom right corner open the contacts list.

![](/files/-LsSj_6frPHDT5wyYN00)

You will see yourself listed. If you want you can chat with yourself but it’s better to create another user and sign in on a chat installed on another device (or simulator instance).

Happy chatting 🙂

Feel free to send feedbacks to <support@frontiere21.it>


