用react-native-gifted-chat构建一个聊天应用

2,334 阅读7分钟

随着对实时通信需求的增长,开发人员正在寻找简单的方法来为移动应用程序添加可靠的通信渠道。在本教程中,我们将学习如何在React Native中使用react-native-gifted-chat为iOS和Android构建移动聊天应用,这个聊天用户界面旨在使应用开发者能够构建跨平台的聊天应用。

要跟上这个教程,你需要。

  • 熟悉CSS、HTML和Javascript ES6
  • 在你的开发机器上安装Node.js和Watchman
  • 用于测试的iOS模拟器或Android仿真器
  • 在你的开发机器上安装一个代码编辑器
  • 对React和React Native有基本了解

让我们开始吧!

React-native-gifted-chat道具

让我们看一下我们将用来创建应用程序的几个内置道具。

  • messages (数组):显示信息
  • text (字符串):输入文本的类型。默认是undefined
  • isTyping (bool): 处理输入指示器的状态。默认值是false
  • timeFormat (字符串):决定时间格式。默认值是LT
  • dateFormat (字符串):决定日期格式。默认值是ll
  • placeholder (文本):空文本字段的占位符。默认值是Type a message...
  • user (对象):发送消息的用户的凭证,即。{_id, name, avatar}
  • messageIdGenerator (函数):为每条新消息生成一个ID。默认为UUID V4

你可以在文档中探索其他道具。

安装 react-native-gifted-chat

让我们从设置一个新的React Native应用开始。打开你的终端,导航到你的工作目录,并运行下面的命令来初始化一个新的React Native应用。

npx react-native init GiftedChatApp

一旦设置完成,导航到GiftedChatApp 目录,运行下面的命令来安装所需的依赖项。

cd GiftedChatApp && npm install @react-navigation/native @react-navigation/stack react-native-gifted-chat react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

上面的命令将在你的项目中安装React Navigation、react-native-gifted-chat和其他必要的依赖项。如果你已经正确设置了一切,你的应用程序应该看起来像下面的截图。

React Native Gifted Chat Dependencies

构建登录屏幕

在我们开始构建登录屏幕之前,让我们更新我们的代码,使App.js 允许屏幕导航。打开App.js ,然后复制并粘贴下面的代码。

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */
import React from 'react';
import {
  StyleSheet,
} from 'react-native';
import {createStackNavigator} from '@react-navigation/stack'
import {NavigationContainer} from '@react-navigation/native';
import LoginScreen from './screens/Login';
const Stack = createStackNavigator();
const App = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator >
        <Stack.Screen name="Login" component={LoginScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
};
const styles = StyleSheet.create({
})
export default App;

让我们安装最后一个依赖项。React Native Elements是一个UI工具包,允许你轻松地创建表单元素和图标。要安装React Native Elements,在你的终端运行下面的代码。

npm install react-native-elements

接下来,导航到你的项目目录,创建一个名为screens 的新文件夹,创建一个名为Login.js 的新文件,然后在Login.js 复制并粘贴下面的代码。

import React, { useState } from 'react';
import { View, StyleSheet } from 'react-native'
import {Input, Button} from 'react-native-elements';
import Icon from 'react-native-vector-icons/FontAwesome';

const Login = () => {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    return (
        <View style={styles.container}>
            <Input
                placeholder='Enter your email'
                label='Email'
                leftIcon={{ type: 'material', name: 'email' }}
                value={email}
                onChangeText={text => setEmail(text)}
            />
            <Input
                placeholder='Enter your password'
                label='Password'
                leftIcon={{ type: 'material', name: 'lock' }}
                value={password}
                onChangeText={text => setPassword(text)}
                secureTextEntry
            />
            <Button title="sign in" style={styles.button} />
            <Button title="register" style={styles.button} />
        </View>
    )
}
const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        padding: 10,
        marginTop: 100,
    },
    button: {
        width: 370,
        marginTop: 10
    }
});

export default Login;

在上面的代码块中,我们导入了useState() Hook,创建了两个状态来存储emailpassword 字段,使用React Native Elements创建了登录输入字段,最后还添加了样式。

现在,运行npx react-native run-ios ,你的应用程序应该看起来像下面的图片。

Install React Native Elements Gifted Chat

构建注册屏幕

现在,让我们建立一个注册屏幕来添加新的用户到我们的应用程序。导航到screens 文件夹,创建一个名为Register.js 的新文件,然后复制并粘贴下面的代码。

import React, { useState } from 'react';
import {View, StyleSheet} from 'react-native'
import { Input, Button } from 'react-native-elements';

const Register = () => {
    const [name, setName] = useState('');
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const [avatar, setAvatar] = useState('');
    return (
        <View style={styles.container}>
            <Input
                placeholder='Enter your name'
                label='Name'
                value={name}
                onChangeText={text => setName(text)}
            />
            <Input
                placeholder='Enter your email'
                label='Email'
                value={email}
                onChangeText={text => setEmail(text)}
            />
            <Input
                placeholder='Enter your password'
                label='Password'
                value={password} onChangeText={text => setPassword(text)}
                secureTextEntry
            />
            <Input
                placeholder='Enter your image url'
                label='Profile Picture'
                value = {avatar}
                onChangeText={text => setAvatar(text)}
            />
            <Button
                title="register" style={styles.button}
            />
        </View>
    )
}
const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        padding: 10,
        marginTop: 100,
    },
    button: {
        width: 370,
        marginTop: 10
    }
})
export default Register;

为React Native设置Firebase

现在你已经完成了登录和注册界面的构建,让我们把Firebase添加到我们的应用程序中来验证用户。

通过运行下面的代码来安装Firebase。

npm install --save @react-native-firebase/app

现在,前往Firebase网站,创建一个名为Gifted Chat App的新项目。

Firebase Project New React Native Project

接下来,我们要在刚刚创建的Firebase项目中添加一个网络应用。在项目的根目录下创建一个名为firebase.js 的新文件。从下面的屏幕上复制firebaseConfig 的凭证。

Firebase Config Credentials Add Web App

用你的项目的独特细节替换目前在firebaseConfig 中的凭证。

import * as firebase from 'firebase';
import 'firebase/auth';
import 'firebase/firestore';

var firebaseConfig = {
    apiKey: "your_api_key",
    authDomain: "your_auth_domain",
    projectId: "your_project_id",
    storageBucket: "your_storage_bucket",
    messagingSenderId: "your_meddage_sender_id",
    appId: "your_app_id"
};

let app;
if (firebase.apps.length === 0) {
    app = firebase.initializeApp(firebaseConfig);
} else {
    app = firebase.app();
}
const db = app.firestore();
const auth = firebase.auth();
export { db, auth };

用Firebase认证一个用户

让我们通过Firebase启用用户认证,使用emailpassword 。在Firebase控制台的侧边栏菜单中点击认证,然后选择Email/Password 。接下来,选择启用保存

Add Authentication Firebase

现在Firebase的设置和配置已经完成,让我们更新一下Register.js 文件来验证一个新的用户。复制下面的代码并把它放在return 函数的上面。

// ... 
const register = () => {
        auth.createUserWithEmailAndPassword(email, password)
            .then((userCredential) => {
                // Signed in 
                var user = userCredential.user;
                // ...
                user.updateProfile({
                    displayName: name,
                    photoUrl: avatar ? avatar : "https://gravatar.com/avatar/94d45dbdba988afacf30d916e7aaad69?s=200&d=mp&r=x",
                })
                    .catch((error) => {
                        alert(error.message)
                    })
            })
            .catch((error) => {
                var errorCode = error.code;
                var errorMessage = error.message;
                // ..
                alert(errorMessage);
            });
    }
//...

首先,我们从先前创建的firebase.js 文件中导入auth 对象。接下来,我们创建了一个注册函数,并将新用户的电子邮件和密码传递给signInWithEmailAndPassword 方法。最后,我们用nameavatar 更新了用户的凭证。

接下来,我们用onPress 处理程序将注册函数传递给注册按钮。

<Button title="register" onPress={register} style={styles.button} />

现在,你可以从你的应用程序中注册一个新用户,并在你的Firebase控制台中列出他们。

Register New User Firebase

构建聊天界面

接下来,我们将建立聊天界面,在那里我们将在用户成功登录后重定向。

screens 目录中创建一个名为Chat.js 的新文件。为了创建一个基本的聊天应用程序,复制并粘贴下面的代码到文件中。

import React, { useEffect, useCallback, useState, useLayoutEffect } from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
import { Avatar } from 'react-native-elements';
import { auth } from '../firebase';
import { GiftedChat } from 'react-native-gifted-chat';



const Chat = ({ navigation }) => {
    const [messages, setMessages] = useState([]);
    const signOut = () => {
        auth.signOut().then(() => {
            // Sign-out successful.
            navigation.replace("Login");
        }).catch((error) => {
            // An error happened.
        });
    }
    useLayoutEffect(() => {
        navigation.setOptions({
            headerLeft: () => (
                <View style={{ marginLeft: 20 }}>
                    <Avatar
                        rounded
                        source={{
                            uri: auth?.currentUser?.photoURL,
                        }}
                    />
                </View>
            ),
            headerRight: () => (
                <TouchableOpacity style={{
                    marginRight: 10
                }}
                    onPress={signOut}
                >
                    <Text>logout</Text>
                </TouchableOpacity>
            )
        })
    }, [navigation]);

    useEffect(() => {
        setMessages([
            {
                _id: 1,
                text: 'Hello developer',
                createdAt: new Date(),
                user: {
                    _id: 2,
                    name: 'React Native',
                    avatar: 'https://placeimg.com/140/140/any',
                },
            },
        ])
    }, [])
    const onSend = useCallback((messages = []) => {
        setMessages(previousMessages => GiftedChat.append(previousMessages, messages))
    }, [])
    return (
        <GiftedChat
            messages={messages}
            showAvatarForEveryMessage={true}
            onSend={messages => onSend(messages)}
            user={{
                _id: auth?.currentUser?.email,
                name: auth?.currentUser?.displayName,
                avatar: auth?.currentUser?.photoURL
            }}
        />
    );
}
const styles = StyleSheet.create({
});
export default Chat;

通过Firebaseauth 对象,我们创建了messages 状态和一个处理用户注销的函数。接下来,我们通过用一个useLayoutEffect 来包装标题nav ,创建了一个基本的导航效果。

通过useEffect Hook,我们创建了一个假消息,并将其安装在GiftedChat 组件上。GiftedChat 组件上的用户道具指的是当前登录的用户,在这种情况下就是你。

现在,你的应用程序应该看起来像下面的屏幕截图。

React Native Gifted Chat Dummy Message

目前,我们的聊天应用程序中的消息并没有存储在任何地方。为了在firestore ,我们将修改onSend 函数来存储消息。

 const onSend = useCallback((messages = []) => {
        setMessages(previousMessages => GiftedChat.append(previousMessages, messages))
        const { _id, createdAt, text, user,} = messages[0]
        db.collection('chats').add({ _id, createdAt,  text, user })
    }, []);

为了从firestore 中检索旧的消息,我们将使用useLayoutEffect ,对数据库进行调用。复制并粘贴下面的代码到onSend 函数上面,以便在聊天屏幕上加载旧信息。

useLayoutEffect(() => {
        const unsubscribe = db.collection('chats').orderBy('createdAt', 'desc').onSnapshot(snapshot => setMessages(
            snapshot.docs.map(doc => ({
                _id: doc.data()._id,
                createdAt: doc.data().createdAt.toDate(),
                text: doc.data().text,
                user: doc.data().user,
            }))
        ));

结论

现在,你知道了如何使用React Native和Firebase构建一个标准的、具有跨平台兼容性的聊天应用程序。我们的应用程序允许我们在多个设备之间聊天,用户数量不限。

react-native-gifted-chat是在React Native中实现聊天的一个很好的工具,可以帮助你在应用中改善沟通。你可以在官方文档中阅读更多关于react-native-gifted-chatFirebase 认证的信息。

The postBuild a chat app with react-native-gifted-chatappeared first onLogRocket Blog.