如何使用Firebase創建Android聊天應用程序
Chinese (Traditional) (中文(繁體)) translation by Zhang Xiang Liang (you can also view the original English article)



使用Firebase創建實時社交應用程序很簡單。 而且您不必編寫壹行服務器端代碼。
在本教程中,我將展示如何利用Firebase UI創建聊天應用程序,您可以與您的朋友分享。 這是壹個非常簡單的應用程序,只有壹個聊天室,對所有用戶開放。
機智如妳,該應用程序依賴於Firebase Auth來管理用戶註冊並登錄。 還使用Firebase的實時數據庫來存儲聊天消息。
準備工作
為了與本教程保持壹致,需要註意以下幾點:
-
最新版本的Android Studio
- 壹個Firebase帳號
如何設置Firebase帳戶並為Android Studio中的Firebase開發做好準備,請參閱Envato Tuts +上我的教程 “入門Firebase for Android”。
1.創建壹個Android Studio項目
啟動Android Studio並創建壹個名為MainActivity的空activity的新項目。



要將項目配置為使用Firebase平臺,請單擊“ 工具”>“Firebase”,打開“Firebase Assistant”窗口。
在使用Firebase平臺的同時,最好將Firebase Analytics添加到項目中。 因此,在Firebase Assistant窗口中,進入Google Analytics(分析)部分,然後點擊Log an Google Analytics(分析)事件。



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



此時,Android Studio項目不僅集成Firebase Analytics,還可以使用所有其他Firebase服務。
2.添加依賴關系
我們將在此項目中使用兩個庫:Firebase UI和Android設計支持庫。 因此,打開app
模塊的build.gradle文件並添加以下compile
依賴項:
compile 'com.android.support:design:23.4.0' compile 'com.firebaseui:firebase-ui:0.6.0'
點擊“ 立即同步”按鈕更新項目。
3.定義布局
已經綁定到MainActivity
的activity_main.xml文件定義了應用程序主界面的內容。 換句話說,它就是聊天室的界面。
像今天可用的其他大多數聊天應用程序壹樣,我們的應用程序具有以下UI元素:
- 按時間順序顯示所有群組聊天消息列表
- 用戶可以輸入新消息的輸入框
- 可以發布消息的按鈕
因此,activity_main.xml必須有ListView
、EditText
和FloatingActionButton
。 將它們全部放入RelativeLayout
布局後,您的布局XML應如下所示:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.tutsplus.mychatapp.MainActivity"> <android.support.design.widget.FloatingActionButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="true" android:src="@drawable/ic_send_black_24dp" android:id="@+id/fab" android:tint="@android:color/white" android:layout_alignParentBottom="true" android:layout_alignParentEnd="true" app:fabSize="mini" /> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toLeftOf="@id/fab" android:layout_alignParentBottom="true" android:layout_alignParentStart="true"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Input" android:id="@+id/input" /> </android.support.design.widget.TextInputLayout> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:layout_alignParentStart="true" android:layout_above="@id/fab" android:dividerHeight="16dp" android:divider="@android:color/transparent" android:id="@+id/list_of_messages" android:layout_marginBottom="16dp"/> </RelativeLayout>
請註意,我把EditText
控件放在TextInputLayout
控件中。 這樣做會給EditText
添加壹個浮動標簽,這樣可以體現MD風格。
現在主界面的布局已經準備好了,我們可以繼續創建聊天消息的布局,ListView
裏面的子item單元。 首先創建壹個名為message.xml的新布局XML文件,該文件的根元素是RelativeLayout
。
該布局必須有TextView
框架來顯示聊天消息的文本,發送的時間及作者。 妳可以隨意放置他們的順序。 布局如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentStart="true" android:id="@+id/message_user" android:textStyle="normal|bold" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/message_user" android:layout_alignParentEnd="true" android:id="@+id/message_time" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/message_user" android:layout_alignParentStart="true" android:layout_marginTop="5dp" android:id="@+id/message_text" android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textSize="18sp" /> </RelativeLayout>
4.處理用戶認證
最好不要允許用戶匿名發布消息到聊天室。 這可能會導致垃圾郵件,安全問題以及不太理想的聊天體驗。 因此,讓我們現在配置我們的應用程序,只有註冊用戶才可以讀取和發送消息。
先從Firebase Console的Auth部分開始,並啟用Email / Password作為登錄提供者。



免費啟用OAuth 2.0登錄提供商。 然而,FirebaseUI v0.6.0無縫地支持Google登錄和Facebook登錄。
步驟1:處理用戶登錄
壹旦應用程序啟動,它必須檢查用戶是否登錄。 登錄後,該應用程序應該繼續顯示聊天室的內容。 否則,它必須將用戶重定向到登錄界面或註冊界面。 使用FirebaseUI創建這些界面比您想像的代碼少得多。
在MainActivity
的onCreate
()方法中,通過檢查當前FirebaseUser
對象是否為null
來檢查用戶是否已經登錄。 如果FirebaseUser對象是null
,您必須創建並配置Intent
對象來打開登錄activity。 為此,請使用SignInIntentBuilder
類。 壹旦Intent準備就緒,您必須使用startActivityForResult
()方法啟動登錄activity。
請註意,登錄activity還允許新用戶註冊。 因此,您沒有寫任何額外的代碼來處理用戶註冊。
將以下代碼添加到onCreate
()方法中:
if(FirebaseAuth.getInstance().getCurrentUser() == null) { // Start sign in/sign up activity startActivityForResult( AuthUI.getInstance() .createSignInIntentBuilder() .build(), SIGN_IN_REQUEST_CODE ); } else { // User is already signed in. Therefore, display // a welcome Toast Toast.makeText(this, "Welcome " + FirebaseAuth.getInstance() .getCurrentUser() .getDisplayName(), Toast.LENGTH_LONG) .show(); // Load chat room contents displayChatMessages(); }
如上面的代碼所示,如果用戶已經登錄,我們首先顯示壹個Toast
歡迎用戶,然後調用名為displayChatMessages的方法。 現在,只需創建壹個存根。 稍後我們會添加代碼。
private void displayChatMessages() { }
壹旦用戶登錄,MainActivity
將收到壹個Intent
形式的結果。 必須重寫onActivityResult
()方法才來處理它。
如果結果的代碼是RESULT_OK
,則表示用戶已成功登錄。 如果是這樣,妳必須()再次調用displayChatMessages
方法。 否則,請調用finish
()方法關閉應用程序。
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode == SIGN_IN_REQUEST_CODE) { if(resultCode == RESULT_OK) { Toast.makeText(this, "Successfully signed in. Welcome!", Toast.LENGTH_LONG) .show(); displayChatMessages(); } else { Toast.makeText(this, "We couldn't sign you in. Please try again later.", Toast.LENGTH_LONG) .show(); // Close the app finish(); } } }
現在,您可以運行應用程序,並查看登錄和註冊屏幕。



步驟2:處理用戶註銷
默認情況下,FirebaseUI使用Smart Lock進行密碼管理。 因此,壹旦用戶登錄,即使應用重新啟動,他們也將保持登錄狀態。 為了允許用戶註銷,我們現在將在MainActivity
的菜單中添加壹個退出選項。
創建壹個名為main_menu.xml的新菜單資源文件,並向其添加壹個item
,其title
屬性設置為註銷。 該文件的內容應如下:
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:title="Sign out" app:showAsAction="never" android:id="@+id/menu_sign_out"/> </menu>
要實例化MainActivity
裏面的菜單資源,重寫onCreateOptionsMenu
()方法並調用MenuInflater
對象的inflate
()方法。
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_menu, menu); return true; }
接下來,重寫onOptionsItemSelected
()方法來處理菜單項上的點擊事件。 在該方法中,您可以調用 AuthUI
類的signOut
()方法來簽名用戶。 因為註銷操作是異步執行的,所以我們還會添加壹個OnCompleteListener
。
@Override public boolean onOptionsItemSelected(MenuItem item) { if(item.getItemId() == R.id.menu_sign_out) { AuthUI.getInstance().signOut(this) .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { Toast.makeText(MainActivity.this, "You have been signed out.", Toast.LENGTH_LONG) .show(); // Close activity finish(); } }); } return true; }
用戶註銷後,應用程式應自動關閉。 這就是為什麽在上面的代碼中調用finish
()方法的原因。
5.創建壹個模型
為了將聊天消息存儲到Firebase實時數據庫中,您必須為它們創建壹個模型。 本教程前面創建的聊天消息的布局有三個視圖。 為了能夠填充這些視圖,模型也必須至少有三個字段。
創建壹個新的Java類ChatMessage.java並添加三個成員變量messageText
、messageUser
和messageTime
。 還要添加壹個構造方法來初始化這些變量。
要使模型與FirebaseUI兼容,您還必須向其添加默認構造方法以及所有成員變量的getter和setter方法。
現在,ChatMessage
類應該如下所示:
public class ChatMessage { private String messageText; private String messageUser; private long messageTime; public ChatMessage(String messageText, String messageUser) { this.messageText = messageText; this.messageUser = messageUser; // Initialize to current time messageTime = new Date().getTime(); } public ChatMessage(){ } public String getMessageText() { return messageText; } public void setMessageText(String messageText) { this.messageText = messageText; } public String getMessageUser() { return messageUser; } public void setMessageUser(String messageUser) { this.messageUser = messageUser; } public long getMessageTime() { return messageTime; } public void setMessageTime(long messageTime) { this.messageTime = messageTime; } }
6.發布聊天消息
現在,該模型已經準備就緒,我們可以輕松地向Firebase實時數據庫添加新的聊天消息。
要發送新消息,用戶要點擊FloatingActionButton
。因此,您必須給它添加OnClickListener
點擊事件。
在監聽器中,您必須首先使用FirebaseDatabase
類的getReference
()方法獲取DatabaseReference
對象。 然後,您可以調用push
()和setValue
()方法將ChatMessage
類的新實例添加到實時數據庫。
這些ChatMessage
實例當然必須使用EditText
的內容進行初始化並且顯示當前登錄的用戶名稱。
因此,將以下代碼添加到onCreate
()方法中:
FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { EditText input = (EditText)findViewById(R.id.input); // Read the input field and push a new instance // of ChatMessage to the Firebase database FirebaseDatabase.getInstance() .getReference() .push() .setValue(new ChatMessage(input.getText().toString(), FirebaseAuth.getInstance() .getCurrentUser() .getDisplayName()) ); // Clear the input input.setText(""); } });
Firebase實時數據庫中的數據始終作為鍵值對存儲。 但是,如果您遵守上述代碼,您將看到我們調用了setValue
()而沒有指定任何鍵。 這僅僅是因為先調用了push
()方法,該方法自動生成壹個新的鍵。
7.顯示聊天消息
FirebaseUI有壹個非常方便的類FirebaseListAdapter,它大大降低了使用Firebase實時數據庫中存在的數據填充ListView
所需的工作量。 我們現在將使用它來獲取和顯示數據庫中存在的所有ChatMessage
對象。
將FirebaseListAdapter
對象添加為MainActivity
類的新成員變量。
private FirebaseListAdapter<ChatMessage> adapter;
在displayChatMessages
()方法中,使用其構造方法初始化適配器,該構造方法需要以下參數:
-
Activity
引用
- 妳感興趣的
class
對象
- 列表子item的布局
- 壹個
DatabaseReference
對象
FirebaseListAdapter
是抽象類,有populateView
()抽象方法,必須被實現該方法。
顧名思義,populateView
()用於填充每個列表項的子item。 如果您熟悉ArrayAdapter
類,您可以將populateView
()方法看作getView
()方法的替代。
在該方法中,您必須首先使用findViewById
()來獲取message.xml布局文件中TextView
的每壹個的引用。 然後,您可以使用ChatMessage
類的getter 來調用它們的setText
()方法並填充它們。
此時,displayChatMessages
()方法的內容應該如下所示:
ListView listOfMessages = (ListView)findViewById(R.id.list_of_messages); adapter = new FirebaseListAdapter<ChatMessage>(this, ChatMessage.class, R.layout.message, FirebaseDatabase.getInstance().getReference()) { @Override protected void populateView(View v, ChatMessage model, int position) { // Get references to the views of message.xml TextView messageText = (TextView)v.findViewById(R.id.message_text); TextView messageUser = (TextView)v.findViewById(R.id.message_user); TextView messageTime = (TextView)v.findViewById(R.id.message_time); // Set their text messageText.setText(model.getMessageText()); messageUser.setText(model.getMessageUser()); // Format the date before showing it messageTime.setText(DateFormat.format("dd-MM-yyyy (HH:mm:ss)", model.getMessageTime())); } }; listOfMessages.setAdapter(adapter);
群聊應用已準備就緒。 運行它並發送壹條新消息,看到它們立即顯示在ListView
中。 如果您與朋友分享該應用程序,您也可以立即看到他們的發送過來的消息。
結論
在本教程中,您學習了如何使用Firebase和FirebaseUI創建壹個非常簡單的群聊應用程序。 您還看到使用FirebaseUI中的類可以輕松實現快速創建新界面並實現復雜功能。
要了解有關Firebase和FirebaseUI的更多信息,請參閱官方文檔。 或者在Envato Tuts +上查看我們的其他Firebase教程。
- ANDROID SDK開始Firebase for AndroidAshraff Hathibelagal
- ANDROID SDK安卓從無到有:Firebase Crash ReportingFirebase Crash Reporting
- JAVASCRIPT使用Firebase作為後臺支持Reginald Dawson