如何使用Firebase创建Android聊天应用

最终产品图片
您将要创造的

使用Firebase ,创建实时社交应用程序就像在公园里散步一样。 最好的事情是:您不必编写任何一行服务器端代码。

在本教程中,我将向您展示如何利用Firebase UI创建可以与朋友共享的gro聊天应用程序。 这将是一个非常简单的应用程序,只有一个聊天室,并且向所有用户开放。

您可能已经猜到了,该应用将依靠Firebase Auth来管理用户注册和登录。它还将使用Firebase的实时数据库来存储群聊消息。

先决条件

为了能够按照本分步教程进行操作,您需要满足以下条件:

1.创建一个Android Studio项目

启动Android Studio并创建一个名为MainActivity的空活动的新项目。

添加空活动

要将项目配置为使用Firebase平台,请通过单击工具> Firebase打开Firebase助手窗口。

使用Firebase平台时,通常最好将Firebase Analytics添加到项目中。 因此,在Firebase Assistant窗口中,转到“ 分析”部分,然后按“ 记录分析事件”

火力助手

接下来,按“ 连接到Firebase”按钮,并确保已选中“ 创建新的Firebase项目”选项。 建立连接后,请按添加分析到您的应用程序按钮。

按向您的应用添加分析

此时,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.定义布局

已经绑定到MainActivityactivity_main.xml文件定义了应用程序主屏幕的内容。 换句话说,它将代表聊天室。

像今天可用的大多数其他群聊应用一样,我们的应用将具有以下UI元素:

  • 以时间顺序显示所有群聊消息的列表
  • 用户可以在其中输入新消息的输入字段
  • 用户可以按下以发布消息的按钮

因此, activity_main.xml必须具有ListViewEditTextFloatingActionButton 。 将它们全部放置在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添加一个浮动标签,如果您要遵守材质设计准则,则这很重要。

现在主屏幕的布局已准备就绪,我们可以继续创建聊天消息的布局,该布局将是ListView项目。 首先创建一个名为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控制台的“身份验证”部分,然后将“ 电子邮件/密码”启用为登录提供程序。


也可以随意启用OAuth 2.0登录提供程序。 但是,FirebaseUI v0.6.0无缝地仅支持Google登录和Facebook登录。

步骤1:处理用户登录

该应用程序启动后,必须检查用户是否已登录。如果已登录,则该应用程序应继续并显示聊天室的内容。 否则,它必须将用户重定向到登录屏幕或注册屏幕。 使用FirebaseUI,创建这些屏幕所需的代码比您想象的要少得多。

MainActivityonCreate()方法中,通过检查当前FirebaseUser对象是否不为null来检查用户是否已经登录。 如果为null ,则必须创建并配置一个Intent对象,该对象打开登录活动。 为此,请使用SignInIntentBuilder类。 准备好意图后,您必须使用startActivityForResult()方法启动登录活动。

请注意,登录活动还允许新用户注册。 因此,您无需编写任何其他代码来处理用户注册。

将以下代码添加到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使用“ 智能锁定”作为“密码” 。 因此,一旦用户登录,即使重新启动该应用程序,他们也将保持登录状态。 为了允许用户注销,我们现在将注销选项添加到MainActivity的溢出菜单中。

创建一个名为main_menu.xml的新菜单资源文件,并向其中添加一个item ,其title属性设置为Sign out 。 该文件的内容应如下所示:

<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对象的MenuInflater inflate()方法。

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

接下来,重写onOptionsItemSelected()方法以处理菜单项上的单击事件。 在该方法内部,可以调用AuthUI类的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实时数据库中,您必须为它们创建一个模型。 我们在本教程前面创建的聊天消息的布局具有三个视图。 为了能够填充这些视图,模型也必须至少具有三个字段。

创建一个名为ChatMessage.java的新Java类, 并向其中添加三个成员变量: messageTextmessageUsermessageTime 。 还添加一个构造函数来初始化这些变量。

为了使模型与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类的新实例添加到实时数据库中。

当然,必须使用EditText的内容和当前登录用户的显示名称来初始化ChatMessage实例。

因此,将以下代码添加到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() 。 之所以允许这样做,是因为在调用setValue()方法之前先调用了push()方法,该方法会自动生成一个新密钥。

7.显示聊天消息

FirebaseUI有一个非常方便的类,称为FirebaseListAdapter ,该类大大减少了使用Firebase实时数据库中存在的数据填充ListView所需的工作。 我们现在将使用它来获取和显示数据库中存在的所有ChatMessage对象。

FirebaseListAdapter对象添加为MainActivity类的新成员变量。

private FirebaseListAdapter<ChatMessage> adapter;

displayChatMessages()方法内部,使用其构造函数初始化适配器,该构造函数需要以下参数:

  • Activity的引用
  • 您感兴趣的对象的class
  • 列表项的布局
  • DatabaseReference对象

FirebaseListAdapter是一个抽象类,并具有一个抽象populateView()方法,该方法必须被覆盖。

顾名思义, populateView()用于填充每个列表项的视图。 如果您熟悉ArrayAdapter类,则可以将populateView()视为getView()方法的替代方法。

在方法内部,必须首先使用findViewById()获取对message.xml布局文件中存在的每个TextView的引用。 然后,您可以调用它们的setText()方法,并使用ChatMessage类的getter填充它们。

此时, 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中可用的类来快速创建新屏幕并实现复杂功能的过程非常容易。

翻译自: https://code.tutsplus.com/tutorials/how-to-create-an-android-chat-app-using-firebase--cms-27397

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值