使用 Firebase 和 Hooks 反应原生聊天应用程序 [第 1 部分]

使用 Firebase 和 Hooks 反应原生聊天应用程序 [第 1 部分]

在本教程中,我们将构建成熟的聊天应用程序。我们可以通过此聊天应用程序共享文本、图像和视频。在第 1 部分中,我们将构建一对一的聊天应用程序,在接下来的部分中,多个参与者将能够通过该应用程序聊天。

首先,确保您具备创建 React-Native 应用程序的所有先决条件 官方文档 .如果您已经完成了该设置,请跳过此文档并继续实施聊天应用程序。

有两种构建聊天应用程序的方法

  1. 基于数据库的方法 ← [第 1 部分]
  2. 基于 Socket IO 的方法 ← [本系列的后续部分]

了解聊天应用程序如何在数据库方法中工作

在实现逻辑之前,您应该知道两个或多个参与者之间如何交换消息。让我们使用下图来理解这一点。

Chat app flow

Chat app flow

“用户 1 向用户 2 发送消息”——这是什么意思?这个流程和我们想象的没什么不同,用户 1 将消息更新到数据库,用户 2 是 订阅 对数据库进行的更新。此外,它会为自己(用户 2)过滤掉消息。用户 1 的流程相同。这是传统的 发布者-订阅者 软件架构模式

此处 UI 将实时更新,但取决于数据库的可用性。如果数据库在某些时候失败,消息将不会更新并且无法在 UI 上看到。

现在我们已经清楚了 Chat Application 的概念,所以我们可以开始设置 React Native 应用程序了。

设置 React Native 应用程序

首先,确保您具备创建 react-native 应用程序的所有先决条件 官方文档 . 运行以下命令创建一个 RN 项目

 // 使用反应原生 CLI  
 $ react-native init ChatApp // 使用 npx  
 $ npx react-native init ChatApp

项目准备好后,您将看到下面的 App 结构:-

Folder structure

我们将使用 反应钩子 实现聊天应用程序逻辑,因为钩子使事情变得更容易和更轻松。创建文件夹 ** 屏幕** 有两个子文件夹作为 ** 密码屏幕** 和 ** 聊天屏幕** (参考上图) ** __** .在 PasswordScreen 文件夹中,我们有处理与密码相关的所有逻辑的 JS 文件。而在 ** 聊天屏幕** 文件夹,所有与聊天屏幕相关的逻辑。

要实现聊天应用程序逻辑,我们必须安装几个 npm 包:

  • React Native 天才聊天
  • 火力基地
  • 反应导航
  • 反应本机手势处理程序
  • React Native Image Picker(你可以阅读我们的博客)
  • React Native 重新动画化
  • 反应原生 UUID
  • 反应本机蒙面视图

运行以下命令来安装这些

 $ npm install react-native-gifted-chat firebase @react-navigation/native @react-navigation/stack react-native-gesture-handler react-native-image-picker react-native-reanimated react-native-uuid @react-本机社区/蒙面视图

让我们从 App.js 逻辑开始

在 App.js 中,我们实现了与 Stack Navigator 相关的逻辑。最初, 密码画面 将被加载,如果输入正确的密码,我们将导航到 聊天画面。

正如我们将要实施的 一对一 聊天时,我们将使用预定义的密码创建两个用户。在添加任何数据之前,您必须设置 firebase 项目并启用 云防火墙 .如果您尚未设置 firebase 项目,请浏览以下部分。

设置 Firebase 项目(可选)

火力基地 并创建您的第一个项目(或使用现有项目)。您的控制台应如下所示

Your Firebase projects all in one place

Your Firebase projects all in one place

笔记 — 创建 Firebase 项目真的很容易,但是如果您仍然遇到任何问题,请按照以下步骤 1-4 这个博客 .

为聊天应用程序设置 Firestore 数据库

转到 Firestore 数据库后,您将看到以下选项: ** + 开始收藏** .我们需要创建 2 个集合 1) ChatMessages 2) ChatUsers。

聊天消息

该集合将包含两个或多个用户之间交换的所有消息。无论是文字、图片还是视频。所有共享/交换的内容都将作为文档保存在此集合中。

 {  
 _id:“6f3c5e08-c255-4c08-b005-4527e46c50e1”  
 创建时间:2022 年 8 月 17 日 22:05:44 UTC+5:30  
 文字:“非常好”  
 用户{  
 _id:“第二个用户”  
 头像:“https://placeimg.com/140/140/any”  
 }  
 }

每个消息文档将如下所示。上面的例子是针对 文本 信息 来自 ** 第二个用户** 至 ** 第一用户** .这里,_id → message doc Id,createdAt → sent on,text → text message,user → sender info。

聊天用户

此集合将仅包含两个用户(对于第 1 部分)。每个用户都有一个链接密码。密码将是每个用户的文档 ID。如果我们想添加一些其他用户,我们只需创建一个带有随机密码作为 ID 的新文档。

ChatUsers Collection

您可以根据自己创建密码并为该用户设置用户名。

Cloud Firestore 就是这样,现在我们可以开始编写一些真正的代码了

Take offf!!

创建密码屏幕

我们将创建一个非常简单的 UI 密码输入框 和一个 继续按钮 验证密码并转到聊天屏幕。 UI 将如下面的屏幕所示。

Enter Password Page

Enter Password Page

下面是 PasswordScreen.js 文件的代码

在上面的代码中,对于 检查密码 () 方法,我们根据输入的密码从 ChatUsers 文档中获取数据。

例如,如果用户输入 0011 作为密码并单击继续,那么我们将在 firestore 数据库中查询“chatUsers/0011”。如果有任何文件,用户将被导航到聊天屏幕,如果没有这样的文件,我们将显示不正确的密码。

firebase.js 文件

在上面的 firebase.js 文件中,我们已经使用 firebaseConfig 初始化了 firebase 项目。这 ** 应用程序** instance 是对 firebase 项目和 ** D b** instance 是对 Cloud Firestore 的引用。

现在密码屏幕已经完成,我们可以进入包含通过文本、图像和视频交换消息的逻辑的聊天屏幕。

创建聊天屏幕

要创建一个聊天屏幕,我们将使用 反应原生的天才聊天 包裹。它将有助于为不同类型的消息(如文本、图像、视频和音频)构建和维护聊天屏幕。聊天屏幕将如下图所示: -

Chat Screen

Chat Screen

登出 按钮将带我们进入密码屏幕,然后 媒体 按钮将要求通过聊天屏幕共享选项(相机、照片和视频)。以下是聊天屏幕的代码:-

第 1 步 — 设置渲染功能

第一步是在视图中呈现有天赋的聊天。为了呈现聊天屏幕,我们需要一个数组(状态变量)来存储两个用户之间交换的消息。 [来自上面 ChatScreen.js 文件中的第 185 行]

 <View style={{display: 'flex', height: '100%'}}>  
 <GiftedChat  
 消息={消息}  
 onSend={消息 => onSend(消息)}  
 用户={{  
 _id:路线?.params?.用户名? route.params.username: '1',  
 }}  
 renderMessageVideo={renderMessageVideo}  
 />  
 </View>

这里 ** 消息** → 状态变量, ** 发送** → 点击发送按钮时调用的方法, ** 用户** → 发件人的身份和 ** 渲染消息视频** → 用于呈现视频消息的方法。

我们通过了 ** route.params.username** 到 GiftedChat 组件中的用户属性。 ** route.params.username** 是登录用户的用户名。我们已经通过密码屏幕(如下图)

 // PasswordScreen.js navigation.navigate('聊天', docSnap.data());

这里 ** docSnap.data()** 是登录用户的信息。正如我们所见,firestore 数据库只有用户名作为用户身份。

第 2 步 — 向用户发送消息(天才聊天组件)

天才聊天提供了一个道具 ** 发送** .当有人点击 GiftedChat 组件中的发送按钮时调用它。下面是 onSend() 方法的代码。 [来自上面 ChatScreen.js 文件中的第 142 行]

 常量 onSend = useCallback((messages = []) => {  
 设置消息(  
 previousMessages => GiftedChat.append(previousMessages, 消息)  
 )  
 const { _id, createdAt, user} = 消息[0]  
 添加文档(  
 集合(数据库,'chatMessages'),  
 {  
 _id,createdAt,文本:messages[0].text,  
 用户:{  
 ...用户,  
 头像:'https://placeimg.com/140/140/any'  
 }  
 }  
 );  
 }, [])

在 onSend Callback 中,我们执行了 2 个函数。

  1. 打电话 ** 设置消息()** 在 Gifted 聊天组件中显示新消息的方法
  2. 更新消息内容 ** 聊天消息** 收藏

第 3 步——在聊天组件中加载旧消息(使用 onSnapshot)

天才聊天视图已加载,但我们还必须显示/加载用户 1 和用户 2 之间交换的旧消息。要加载这些消息,我们添加一个 ** 使用效果布局** 方法。 [来自上面 ChatScreen.js 文件中的第 14 行]

 使用布局效果(()=> {  
 导航.setOptions({  
 headerRight: () => (  
 <TouchableOpacity style={{marginRight: 10}}  
 onPress={gotoMedia}>  
 <Text>媒体</Text>  
 </TouchableOpacity>  
 )  
 }) 常量 q = 查询(  
 集合(数据库,'chatMessages'),  
 orderBy('createdAt', 'desc')  
 );  
 const unsubscribe = onSnapshot(q, (snapshot) =>  
 setMessages(snapshot.docs.map(doc => ({  
 _id: doc.data()._id,  
 createdAt: doc.data().createdAt.toDate(),  
 文本:doc.data().text,  
 用户:doc.data().user,  
 图片:doc.data().image,  
 视频:doc.data().video  
 }))  
 ));  
 返回 () => {  
 取消订阅();  
 };  
 }, [导航]);

onSnapshot() 方法有助于订阅集合更改。例如 ** onSnapshot()** 方法被调用 ** 聊天消息** 集合,然后每当添加一个文档时 ** 聊天消息** 集合,将调用此方法。

所以我们添加了一个逻辑,每当添加一个文档时 ** 聊天消息** .我们使用更新消息状态变量 ** 设置消息()** 方法。和这个 ** 消息** state 变量被进一步传递到 GiftedChat 组件中。

在 React 原生天才聊天中共享图像和视频

我们已经看到,我们如何通过更新到数据库来共享文本消息,onSnapshot 将捕获该消息并将消息加载到接收者聊天组件中。但是对于图像和视频,它有点不同。

如果你是 ** 分享图片** , 那么下面将是共享消息的格式

 {  
 _id:“6f3c5e08-c255-4c08-b005-4527e46c50e1”  
 创建时间:2022 年 8 月 17 日 22:05:44 UTC+5:30  
 图片: ”[ https://picsum.photos/200/300](https://picsum.photos/200/300) "  
 用户{  
 _id:“第二个用户”  
 头像:“https://placeimg.com/140/140/any”  
 }  
 }

如果你 ** 分享视频** 那么下面将是共享消息的格式

 {  
 _id:“6f3c5e08-c255-4c08-b005-4527e46c50e1”  
 创建时间:2022 年 8 月 17 日 22:05:44 UTC+5:30  
 视频: ”<video_url> "  
 用户{  
 _id:“第二个用户”  
 头像:“https://placeimg.com/140/140/any”  
 }

对于图像和视频,我们将首先将实际的视频和图像上传到 Firebase 存储。 Firebase 存储提供了指向该图像/视频的链接。此外,该链接将用于在 Gifted 聊天组件中显示图像/视频。

**媒体选项
** 提供了媒体选项,我们可以使用它上传相机图像、库图像或视频。下面是使用操作表显示这些选项的代码。 [来自上述 ChatScreen.js 文件中的第 41 行]

 ActionSheetIOS.showActionSheetWithOptions(  
 {  
 选项:[“取消”、“相机”、“照片”、“视频”]、  
 取消按钮索引:0  
 },  
 按钮索引 => {  
 if (buttonIndex == 1) {  
 // 相机按钮事件  
 } else if (buttonIndex == 2) {  
 // 照片按钮事件  
 } else if (buttonIndex == 3) {  
 // 视频按钮事件  
 }  
 })

Media option

Media option

**将图片和视频上传到 Firebase 存储
** 上传相机图像和库图像的过程将相同,但上传视频会有所不同。 [来自上述 ChatScreen.js 文件的第 40 行]

 常量 gotoMedia = () => {  
 ActionSheetIOS.showActionSheetWithOptions({  
 选项:[“取消”、“相机”、“照片”、“视频”]、  
 取消按钮索引:0  
 },  
 按钮索引 => {  
 if (buttonIndex == 2) {  
 launchImageLibrary().then((res) => {  
 if (!res.didCancel && !res.errorCode) {  
 uploadMediaToFirestore(res, 'image');  
 }  
 });  
 } else if (buttonIndex == 1) {  
 launchCamera().then((res) => {  
 if (!res.didCancel && !res.errorCode) {  
 uploadMediaToFirestore(res, 'image');  
 }  
 });  
 } else if (buttonIndex == 3) {  
 常量选项 = {  
 标题:'视频选择器',  
 mediaType: '视频',  
 };  
 launchImageLibrary(options).then((res) => {  
 if (!res.didCancel && !res.errorCode) {  
 uploadMediaToFirestore(res, 'video');  
 }  
 });  
 }  
 })  
 }

注意:- 请按照 安装后步骤 完成设置并在应用程序中使用反应原生图像选择器。

我们正在使用 反应原生图像选择器 打开相机并选择照片和视频。打开 ** 相机** → ** 启动相机()** 方法,打开 ** 照片库** → ** 启动图像库()** 方法和打开 ** 视频库** → ** 启动图像库(选项)** 方法。

选择图像或视频后,我们会将响应传递给 ** 上传媒体到Firestore()** 方法。下面是代码 ** 上传媒体到Firestore()** 方法 [来自上述 ChatScreen.js 文件的第 73 行]

 const uploadMediaToFirestore = async (res, type) => {  
 常量 uri = res.assets[0].uri;  
 常量文件名 = uri.substring(uri.lastIndexOf('/') + 1);  
 常量上传Uri =  
 Platform.OS === 'ios' ? uri.replace('file://', ​​'') : uri;  
 常量存储 = getStorage(app);  
 const fileRef = ref(存储,文件名);  
 const img = await fetch(uploadUri);  
 常量字节 = 等待 img.blob();  
 让元数据;  
 如果(类型=='视频'){  
 元数据 = {  
 contentType: '视频/mp4',  
 };  
 } 别的 {  
 元数据 = {  
 内容类型:'图像/JPEG',  
 };  
 }  
 uploadBytes(fileRef, bytes, metadata).then(async (uploadTask) => {  
 console.log('task', uploadTask)  
 getDownloadURL(uploadTask.ref).then((url) => {  
 如果(类型=='视频'){  
 设置视频数据(网址);  
 } 别的 {  
 设置图像数据(网址);  
 }  
 });  
 }).catch((错误) => {  
 alert('上传图片出错!')  
 控制台日志(错误);  
 });  
 }

首先,我们获取图像/视频路径并将其更改为 blob 类型。进一步基于 type 参数,我们将元数据对象传递给上传字节函数。上传图片/视频后,调用 getDownloadURL() 方法获取存储链接。

媒体(图像/视频)链接现已更新为 ** 信息** 状态变量和云 Firestore 使用 ** 设置视频数据(网址)** 和 ** 设置图像数据(网址)** 方法。以下是共享图像和视频的屏幕截图。

Shared media

Shared media

结论

现在我们知道如何使用 firebase 和 Hooks 创建一个带有 react-native-gifted-chat 的聊天应用程序。您可以以文本、图像和视频的形式共享消息。如果您想了解更多关于任何其他功能实现的信息,请关注 → ** __**enappd.com

敬请关注 !!

下一步

如果您喜欢这个博客,您还会发现以下 React Native 博客很有趣且很有帮助。欢迎在评论区提出任何问题

如果你需要一个基础来启动你的下一个 React Native 应用程序,你可以使用 React Native 完整应用

React Native Full App by Enappd

React Native Full App by Enappd

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/36998/23461612

posted @ 2022-09-16 12:24  哈哈哈来了啊啊啊  阅读(76)  评论(0编辑  收藏  举报