Advertisement
  1. Code
  2. Mobile Development
  3. Android Development

如何使用Firebase創建Android聊天應用程序

Scroll to top
Read Time: 4 min

() translation by (you can also view the original English article)

Final product imageFinal product imageFinal product image
What You'll Be Creating

使用Firebase創建實時社交應用程序很簡單。  而且您不必編寫壹行服務器端代碼。

在本教程中,我將展示如何利用Firebase UI創建聊天應用程序,您可以與您的朋友分享。  這是壹個非常簡單的應用程序,只有壹個聊天室,對所有用戶開放。

機智如妳,該應用程序依賴於Firebase Auth來管理用戶註冊並登錄。  還使用Firebase的實時數據庫來存儲聊天消息。

準備工作

為了與本教程保持壹致,需要註意以下幾點:

如何設置Firebase帳戶並為Android Studio中的Firebase開發做好準備,請參閱Envato Tuts +上我的教程 “入門Firebase for Android”。

1.創建壹個Android Studio項目

啟動Android Studio並創建壹個名為MainActivity的空activity的新項目。

Add empty activityAdd empty activityAdd empty activity

要將項目配置為使用Firebase平臺,請單擊“ 工具”>“Firebase”,打開“Firebase Assistant”窗口。

在使用Firebase平臺的同時,最好將Firebase Analytics添加到項目中。  因此,在Firebase Assistant窗口中,進入Google Analytics(分析)部分,然後點擊Log an Google Analytics(分析)事件。

Firebase AssistantFirebase AssistantFirebase Assistant

接下來,點擊“ 連接到Firebase”按鈕,確保選擇了“ 創建新的Firebase項目”選項。  建立連接後,點擊“ 添加Google Analytics(分析)”按鈕。

Press Add analytics to your appPress Add analytics to your appPress Add analytics to your app

此時,Android Studio項目不僅集成Firebase Analytics,還可以使用所有其他Firebase服務。

2.添加依賴關系

我們將在此項目中使用兩個庫:Firebase UI和Android設計支持庫。  因此,打開app模塊的build.gradle文件並添加以下compile依賴項:

1
compile 'com.android.support:design:23.4.0'
2
compile 'com.firebaseui:firebase-ui:0.6.0'

點擊“ 立即同步”按鈕更新項目。

3.定義布局

已經綁定到MainActivityactivity_main.xml文件定義了應用程序主界面的內容。  換句話說,它就是聊天室的界面。

像今天可用的其他大多數聊天應用程序壹樣,我們的應用程序具有以下UI元素:

  • 按時間順序顯示所有群組聊天消息列表
  • 用戶可以輸入新消息的輸入框
  • 可以發布消息的按鈕

因此,activity_main.xml必須有ListViewEditTextFloatingActionButton。  將它們全部放入RelativeLayout布局後,您的布局XML應如下所示:

1
<?xml version="1.0" encoding="utf-8"?>
2
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
3
    xmlns:app="http://schemas.android.com/apk/res-auto"
4
    xmlns:tools="http://schemas.android.com/tools"
5
    android:id="@+id/activity_main"
6
    android:layout_width="match_parent"
7
    android:layout_height="match_parent"
8
    android:paddingBottom="@dimen/activity_vertical_margin"
9
    android:paddingLeft="@dimen/activity_horizontal_margin"
10
    android:paddingRight="@dimen/activity_horizontal_margin"
11
    android:paddingTop="@dimen/activity_vertical_margin"
12
    tools:context="com.tutsplus.mychatapp.MainActivity">
13
14
    <android.support.design.widget.FloatingActionButton
15
        android:layout_width="wrap_content"
16
        android:layout_height="wrap_content"
17
        android:clickable="true"
18
        android:src="@drawable/ic_send_black_24dp"
19
        android:id="@+id/fab"
20
        android:tint="@android:color/white"
21
        android:layout_alignParentBottom="true"
22
        android:layout_alignParentEnd="true"
23
        app:fabSize="mini" />
24
25
    <android.support.design.widget.TextInputLayout
26
        android:layout_width="match_parent"
27
        android:layout_height="wrap_content"
28
        android:layout_toLeftOf="@id/fab"
29
        android:layout_alignParentBottom="true"
30
        android:layout_alignParentStart="true">
31
32
        <EditText
33
            android:layout_width="match_parent"
34
            android:layout_height="wrap_content"
35
            android:hint="Input"
36
            android:id="@+id/input"
37
            />
38
    </android.support.design.widget.TextInputLayout>
39
40
    <ListView
41
        android:layout_width="match_parent"
42
        android:layout_height="match_parent"
43
        android:layout_alignParentTop="true"
44
        android:layout_alignParentStart="true"
45
        android:layout_above="@id/fab"
46
        android:dividerHeight="16dp"
47
        android:divider="@android:color/transparent"
48
        android:id="@+id/list_of_messages"
49
        android:layout_marginBottom="16dp"/>
50
</RelativeLayout>

請註意,我把EditText控件放在TextInputLayout控件中。  這樣做會給EditText添加壹個浮動標簽,這樣可以體現MD風格。

現在主界面的布局已經準備好了,我們可以繼續創建聊天消息的布局,ListView裏面的子item單元。  首先創建壹個名為message.xml的新布局XML文件,該文件的根元素是RelativeLayout

該布局必須有TextView框架來顯示聊天消息的文本,發送的時間及作者。  妳可以隨意放置他們的順序。  布局如下:

1
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2
    android:layout_width="match_parent" android:layout_height="match_parent">
3
4
    <TextView
5
        android:layout_width="wrap_content"
6
        android:layout_height="wrap_content"
7
        android:layout_alignParentTop="true"
8
        android:layout_alignParentStart="true"
9
        android:id="@+id/message_user"
10
        android:textStyle="normal|bold" />
11
12
    <TextView
13
        android:layout_width="wrap_content"
14
        android:layout_height="wrap_content"
15
        android:layout_alignBottom="@+id/message_user"
16
        android:layout_alignParentEnd="true"
17
        android:id="@+id/message_time" />
18
19
    <TextView
20
        android:layout_width="wrap_content"
21
        android:layout_height="wrap_content"
22
        android:layout_below="@+id/message_user"
23
        android:layout_alignParentStart="true"
24
        android:layout_marginTop="5dp"
25
        android:id="@+id/message_text"
26
        android:textAppearance="@style/TextAppearance.AppCompat.Body1"
27
        android:textSize="18sp" />
28
</RelativeLayout>

4.處理用戶認證

最好不要允許用戶匿名發布消息到聊天室。  這可能會導致垃圾郵件,安全問題以及不太理想的聊天體驗。  因此,讓我們現在配置我們的應用程序,只有註冊用戶才可以讀取和發送消息。

先從Firebase ConsoleAuth部分開始,並啟用Email / Password作為登錄提供者。

免費啟用OAuth 2.0登錄提供商。  然而,FirebaseUI v0.6.0無縫地支持Google登錄和Facebook登錄。

步驟1:處理用戶登錄

壹旦應用程序啟動,它必須檢查用戶是否登錄。  登錄後,該應用程序應該繼續顯示聊天室的內容。  否則,它必須將用戶重定向到登錄界面或註冊界面。  使用FirebaseUI創建這些界面比您想像的代碼少得多。

MainActivityonCreate()方法中,通過檢查當前FirebaseUser對象是否為null來檢查用戶是否已經登錄。  如果FirebaseUser對象是null,您必須創建並配置Intent對象來打開登錄activity。  為此,請使用SignInIntentBuilder類。  壹旦Intent準備就緒,您必須使用startActivityForResult()方法啟動登錄activity。

請註意,登錄activity還允許新用戶註冊。  因此,您沒有寫任何額外的代碼來處理用戶註冊。

將以下代碼添加到onCreate()方法中:

1
if(FirebaseAuth.getInstance().getCurrentUser() == null) {
2
    // Start sign in/sign up activity

3
    startActivityForResult(
4
            AuthUI.getInstance()
5
            .createSignInIntentBuilder()
6
            .build(),
7
            SIGN_IN_REQUEST_CODE
8
    );
9
} else {
10
    // User is already signed in. Therefore, display

11
    // a welcome Toast

12
    Toast.makeText(this,
13
            "Welcome " + FirebaseAuth.getInstance()
14
                    .getCurrentUser()
15
                    .getDisplayName(),
16
            Toast.LENGTH_LONG)
17
            .show();
18
19
    // Load chat room contents

20
    displayChatMessages();
21
}

如上面的代碼所示,如果用戶已經登錄,我們首先顯示壹個Toast歡迎用戶,然後調用名為displayChatMessages的方法。  現在,只需創建壹個存根。  稍後我們會添加代碼。

1
private void displayChatMessages() {
2
3
}

壹旦用戶登錄,MainActivity將收到壹個Intent形式的結果。  必須重寫onActivityResult()方法才來處理它。

如果結果的代碼是RESULT_OK,則表示用戶已成功登錄。  如果是這樣,妳必須()再次調用displayChatMessages方法。  否則,請調用finish()方法關閉應用程序。

1
@Override
2
protected void onActivityResult(int requestCode, int resultCode, 
3
                                            Intent data) {
4
    super.onActivityResult(requestCode, resultCode, data);
5
6
    if(requestCode == SIGN_IN_REQUEST_CODE) {
7
        if(resultCode == RESULT_OK) {
8
            Toast.makeText(this,
9
                    "Successfully signed in. Welcome!",
10
                    Toast.LENGTH_LONG)
11
                    .show();
12
            displayChatMessages();
13
        } else {
14
            Toast.makeText(this,
15
                    "We couldn't sign you in. Please try again later.",
16
                    Toast.LENGTH_LONG)
17
                    .show();
18
19
            // Close the app

20
            finish();
21
        }
22
    }
23
24
}

現在,您可以運行應用程序,並查看登錄和註冊屏幕。

Sign up screen for new usersSign up screen for new usersSign up screen for new users

步驟2:處理用戶註銷

默認情況下,FirebaseUI使用Smart Lock進行密碼管理。  因此,壹旦用戶登錄,即使應用重新啟動,他們也將保持登錄狀態。  為了允許用戶註銷,我們現在將在MainActivity的菜單中添加壹個退出選項。

創建壹個名為main_menu.xml的新菜單資源文件,並向其添加壹個item,其title屬性設置為註銷。  該文件的內容應如下:

1
<menu xmlns:android="http://schemas.android.com/apk/res/android"
2
    xmlns:app="http://schemas.android.com/apk/res-auto">
3
4
    <item android:title="Sign out" app:showAsAction="never"
5
        android:id="@+id/menu_sign_out"/>
6
7
</menu>

要實例化MainActivity裏面的菜單資源,重寫onCreateOptionsMenu()方法並調用MenuInflater對象的inflate()方法。

1
@Override
2
public boolean onCreateOptionsMenu(Menu menu) {
3
    getMenuInflater().inflate(R.menu.main_menu, menu);
4
    return true;
5
}

接下來,重寫onOptionsItemSelected()方法來處理菜單項上的點擊事件。  在該方法中,您可以調用 AuthUI類的signOut()方法來簽名用戶。  因為註銷操作是異步執行的,所以我們還會添加壹個OnCompleteListener

1
@Override
2
public boolean onOptionsItemSelected(MenuItem item) {
3
    if(item.getItemId() == R.id.menu_sign_out) {
4
        AuthUI.getInstance().signOut(this)
5
            .addOnCompleteListener(new OnCompleteListener<Void>() {
6
                @Override
7
                public void onComplete(@NonNull Task<Void> task) {
8
                    Toast.makeText(MainActivity.this,
9
                            "You have been signed out.",
10
                            Toast.LENGTH_LONG)
11
                            .show();
12
13
                    // Close activity

14
                    finish();
15
                }
16
            });
17
    }
18
    return true;
19
}

用戶註銷後,應用程式應自動關閉。  這就是為什麽在上面的代碼中調用finish()方法的原因。

5.創建壹個模型

為了將聊天消息存儲到Firebase實時數據庫中,您必須為它們創建壹個模型。  本教程前面創建的聊天消息的布局有三個視圖。  為了能夠填充這些視圖,模型也必須至少有三個字段。

創建壹個新的Java類ChatMessage.java並添加三個成員變量messageTextmessageUsermessageTime。  還要添加壹個構造方法來初始化這些變量。

要使模型與FirebaseUI兼容,您還必須向其添加默認構造方法以及所有成員變量的getter和setter方法。

現在,ChatMessage類應該如下所示:

1
public class ChatMessage {
2
3
    private String messageText;
4
    private String messageUser;
5
    private long messageTime;
6
7
    public ChatMessage(String messageText, String messageUser) {
8
        this.messageText = messageText;
9
        this.messageUser = messageUser;
10
11
        // Initialize to current time

12
        messageTime = new Date().getTime();
13
    }
14
15
    public ChatMessage(){
16
17
    }
18
19
    public String getMessageText() {
20
        return messageText;
21
    }
22
23
    public void setMessageText(String messageText) {
24
        this.messageText = messageText;
25
    }
26
27
    public String getMessageUser() {
28
        return messageUser;
29
    }
30
31
    public void setMessageUser(String messageUser) {
32
        this.messageUser = messageUser;
33
    }
34
35
    public long getMessageTime() {
36
        return messageTime;
37
    }
38
39
    public void setMessageTime(long messageTime) {
40
        this.messageTime = messageTime;
41
    }
42
}

6.發布聊天消息

現在,該模型已經準備就緒,我們可以輕松地向Firebase實時數據庫添加新的聊天消息。

要發送新消息,用戶要點擊FloatingActionButton。因此,您必須給它添加OnClickListener點擊事件。

在監聽器中,您必須首先使用FirebaseDatabase類的getReference()方法獲取DatabaseReference對象。  然後,您可以調用push()和setValue()方法將ChatMessage類的新實例添加到實時數據庫。

這些ChatMessage實例當然必須使用EditText的內容進行初始化並且顯示當前登錄的用戶名稱。

因此,將以下代碼添加到onCreate()方法中:

1
FloatingActionButton fab = 
2
        (FloatingActionButton)findViewById(R.id.fab);
3
4
fab.setOnClickListener(new View.OnClickListener() {
5
    @Override
6
    public void onClick(View view) {
7
        EditText input = (EditText)findViewById(R.id.input);
8
9
        // Read the input field and push a new instance

10
        // of ChatMessage to the Firebase database

11
        FirebaseDatabase.getInstance()
12
                .getReference()
13
                .push()
14
                .setValue(new ChatMessage(input.getText().toString(),
15
                        FirebaseAuth.getInstance()
16
                                .getCurrentUser()
17
                                .getDisplayName())
18
                );
19
20
        // Clear the input

21
        input.setText("");
22
    }
23
});

Firebase實時數據庫中的數據始終作為鍵值對存儲。  但是,如果您遵守上述代碼,您將看到我們調用了setValue()而沒有指定任何鍵。  這僅僅是因為先調用了push()方法,該方法自動生成壹個新的鍵。

7.顯示聊天消息

FirebaseUI有壹個非常方便的類FirebaseListAdapter,它大大降低了使用Firebase實時數據庫中存在的數據填充ListView所需的工作量。  我們現在將使用它來獲取和顯示數據庫中存在的所有ChatMessage對象。

FirebaseListAdapter對象添加為MainActivity類的新成員變量。

1
private FirebaseListAdapter<ChatMessage> adapter;

displayChatMessages()方法中,使用其構造方法初始化適配器,該構造方法需要以下參數:

  • Activity引用
  • 妳感興趣的class對象
  • 列表子item的布局
  • 壹個DatabaseReference對象

FirebaseListAdapter是抽象類,有populateView()抽象方法,必須被實現該方法。

顧名思義,populateView()用於填充每個列表項的子item。  如果您熟悉ArrayAdapter類,您可以將populateView()方法看作getView()方法的替代。

在該方法中,您必須首先使用findViewById()來獲取message.xml布局文件中TextView的每壹個的引用。  然後,您可以使用ChatMessage類的getter 來調用它們的setText()方法並填充它們。

此時,displayChatMessages()方法的內容應該如下所示:

1
ListView listOfMessages = (ListView)findViewById(R.id.list_of_messages);
2
3
adapter = new FirebaseListAdapter<ChatMessage>(this, ChatMessage.class,
4
        R.layout.message, FirebaseDatabase.getInstance().getReference()) {
5
    @Override
6
    protected void populateView(View v, ChatMessage model, int position) {
7
        // Get references to the views of message.xml

8
        TextView messageText = (TextView)v.findViewById(R.id.message_text);
9
        TextView messageUser = (TextView)v.findViewById(R.id.message_user);
10
        TextView messageTime = (TextView)v.findViewById(R.id.message_time);
11
12
        // Set their text

13
        messageText.setText(model.getMessageText());
14
        messageUser.setText(model.getMessageUser());
15
16
        // Format the date before showing it

17
        messageTime.setText(DateFormat.format("dd-MM-yyyy (HH:mm:ss)",
18
                model.getMessageTime()));
19
    }
20
};
21
22
listOfMessages.setAdapter(adapter);

群聊應用已準備就緒。  運行它並發送壹條新消息,看到它們立即顯示在ListView中。  如果您與朋友分享該應用程序,您也可以立即看到他們的發送過來的消息。

結論

在本教程中,您學習了如何使用Firebase和FirebaseUI創建壹個非常簡單的群聊應用程序。  您還看到使用FirebaseUI中的類可以輕松實現快速創建新界面並實現復雜功能。

要了解有關Firebase和FirebaseUI的更多信息,請參閱官方文檔。  或者在Envato Tuts +上查看我們的其他Firebase教程。


关注我们的公众号
Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.