логотип PurpleSchool
логотип PurpleSchool

Создание чат-приложения на React Native

Автор

Олег Марков

Введение

Чат-приложения — одни из самых популярных продуктов, которые разрабатывают на мобильных и веб-платформах. Реализация функционального чата — отличный способ освоить навыки работы с React Native, научиться хранить данные в облаке и общаться в реальном времени. В этой статье вы увидите, как можно реализовать простой, но мощный чат на React Native используя современный стек технологий, познакомитесь с детальной структурой приложения и увидите реальные примеры кода. Разберем, как реализовать базовые и расширенные функции: отправку сообщений, отображение чата, авторизацию и подключение к облачной базе данных.

Почему выбирают React Native для чатов

React Native позволяет писать кроссплатформенные мобильные приложения на JavaScript, а результат запускается на iOS и Android с нативной производительностью UI. Для чата нам критично получить мгновенный отклик, плавную работу интерфейса и легкое управление состоянием сообщений. С инфраструктурой React Native это становится особенно удобно:

  • Большая экосистема готовых библиотек (например, Gifted Chat для UI).
  • Простое масштабирование и интеграция с realtime-службами (Firebase, Supabase).
  • Высокая скорость разработки для обеих платформ.

Давайте шаг за шагом посмотрим, как реализовать собственный чат.

Создание чат-приложения на React Native требует знаний в области сетевых технологий, баз данных и управления состоянием. Необходимо уметь устанавливать соединение с сервером, отправлять и получать сообщения, отображать их в реальном времени и управлять пользовательскими сессиями. Для создания хорошего чат-приложения нужно иметь представления о работе с сокетами и стримингом данных. Если вы хотите детальнее погрузиться в создание чат-приложений и другие сетевые возможности в React Native, — приходите на наш большой курс React Native и Expo Router. На курсе 184 уроков и 11 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.

Подготовка и настройка проекта

Установка React Native

Для начала необходимо создать новый проект. Если у вас еще не установлен React Native CLI, это можно сделать так:

npm install -g react-native-cli

Затем создайте проект:

npx react-native init ChatApp
cd ChatApp

Запуск эмулятора

Вы можете запустить эмулятор (или приложение на устройстве). Для iOS:

npx react-native run-ios

Для Android:

npx react-native run-android

Убедитесь, что эмулятор (или телефон) подключён.

Добавление зависимостей

Нам понадобятся следующие библиотеки:

  • @react-navigation/native (навигация по экрану)
  • react-native-gifted-chat (быстрый старт для UI чата)
  • firebase (бэкенд и хранение сообщений)
  • Дополнительно: @react-navigation/stack, @react-native-firebase/app, @react-native-firebase/auth, @react-native-firebase/firestore

Устанавливаем их:

npm install @react-navigation/native @react-navigation/stack
npm install react-native-gifted-chat
npm install firebase

Если планируете использовать расширенные возможности Firebase с нативной производительностью, добавьте:

npm install @react-native-firebase/app @react-native-firebase/auth @react-native-firebase/firestore

Архитектура приложения

Чат-приложение, как правило, состоит из следующих ключевых компонентов:

  • Экран авторизации (логин/регистрация)
  • Основной экран списка чатов или сообщений
  • Форма для отправки и отображения сообщений
  • Сервис для работы с бэкендом (например, Firebase)
  • Управление состоянием (выбор между useState, useReducer или отдельными библиотеками)

Перед тем как перейти к самому коду, давайте схематично рассмотрим взаимосвязи между модулями:

[AuthScreen] -> [ChatScreen] <-> [Firebase (Firestore, Auth)]

Интеграция с Firebase

Чтобы чат работал в реальном времени, выберем облачную базу данных. Самый популярный вариант — Firebase Firestore.

1. Создание проекта в Firebase

Перейдите на https://console.firebase.google.com и создайте новый проект.

Добавьте новое приложение (Android/iOS), следуйте инструкции. Firebase сгенерирует для вас параметры конфигурации.

2. Подключение Firebase к приложению

В каталоге проекта создайте файл firebase.js и поместите туда следующее:

// Импортируем модуль firebase/app и firebase/firestore
import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';

// Данные из вашей консоли Firebase
const firebaseConfig = {
  apiKey: "ВАШ_API_KEY",
  authDomain: "ВАШ_AUTH_DOMAIN",
  projectId: "ВАШ_PROJECT_ID",
  storageBucket: "ВАШ_STORAGE_BUCKET",
  messagingSenderId: "ВАШ_MESSAGING_SENDER_ID",
  appId: "ВАШ_APP_ID",
};

const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);

Сохраните ключи из вашей консоли Firebase. Теперь база данных подключена.

Реализация экрана авторизации

Аутентификация не обязательна для минимального чата, но это стандарт для современных приложений. Чтобы реализовать простой логин, можно использовать базу email+password.

Создайте компонент AuthScreen.js:

import React, { useState } from 'react';
import { View, TextInput, Button, Text } from 'react-native';
import { getAuth, signInWithEmailAndPassword, createUserWithEmailAndPassword } from 'firebase/auth';

// Получаем инстанс аутентификации
const auth = getAuth();

export default function AuthScreen({ navigation }) {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');

  const handleLogin = async () => {
    try {
      await signInWithEmailAndPassword(auth, email, password);
      navigation.replace('Chat');
    } catch (err) {
      setError('Ошибка входа. Проверьте данные.');
    }
  };

  const handleRegister = async () => {
    try {
      await createUserWithEmailAndPassword(auth, email, password);
      navigation.replace('Chat');
    } catch (err) {
      setError('Ошибка регистрации.');
    }
  };

  return (
    <View>
      <TextInput placeholder="Email" onChangeText={setEmail} value={email} />
      <TextInput placeholder="Пароль" secureTextEntry onChangeText={setPassword} value={password} />
      <Button title="Войти" onPress={handleLogin} />
      <Button title="Зарегистрироваться" onPress={handleRegister} />
      {error ? <Text>{error}</Text> : null}
    </View>
  );
}

В этом компоненте предусмотрены обе функции — вход и регистрация.

Экран чата: отправка и получение сообщений

Рассмотрим основной экран приложения. Здесь появится чат-интерфейс и фоновая подписка на обновления Firestore.

Настройка Gifted Chat

Gifted Chat прост в использовании, автоматизирует рендеринг сообщений, аватаров и поля ввода. Сначала импортируем:

import React, { useState, useCallback, useEffect } from 'react';
import { GiftedChat } from 'react-native-gifted-chat';
import { collection, addDoc, onSnapshot, query, orderBy } from 'firebase/firestore';
import { db } from './firebase';

Весь компонент

Давайте напишем основной экран:

export default function ChatScreen() {
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    // Создаём запрос к коллекции "messages" с сортировкой от новых к старым
    const q = query(collection(db, 'messages'), orderBy('createdAt', 'desc'));
    // Подписка на обновления
    const unsubscribe = onSnapshot(q, (snapshot) => {
      setMessages(
        snapshot.docs.map(doc => ({
          _id: doc.id, // id документа - id сообщения в Gifted Chat
          text: doc.data().text,
          createdAt: doc.data().createdAt.toDate(),
          user: doc.data().user,
        }))
      );
    });

    // Очистка подписки при размонтировании компонента
    return () => unsubscribe();
  }, []);

  const onSend = useCallback(async (messages = []) => {
    // Добавляем новое сообщение в Firestore
    const { _id, createdAt, text, user } = messages[0];
    await addDoc(collection(db, 'messages'), {
      _id,
      createdAt,
      text,
      user
    });
  }, []);

  return (
    <GiftedChat
      messages={messages}
      onSend={messages => onSend(messages)}
      user={{
        _id: '1', // Статично, но хорошо делать динамически на основе пользователя
        name: 'User'
      }}
      placeholder="Введите сообщение..."
    />
  );
}

Обратите внимание:

  • Команда onSnapshot слушает коллекцию сообщений в Firestore, обновляет список сообщений на экране в реальном времени.
  • onSend сразу добавляет новое сообщение в базу.
  • user._id должен быть уникальным для пользователя. Обычно его берут из firebase.auth().currentUser.uid.

Навигация между экранами

Реализуем простую стек-навигацию между экранами авторизации и чата.

В корневом файле App.js напишите:

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

import AuthScreen from './AuthScreen';
import ChatScreen from './ChatScreen';

const Stack = createStackNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Auth" component={AuthScreen} options={{ title: 'Вход' }} />
        <Stack.Screen name="Chat" component={ChatScreen} options={{ title: 'Чат' }} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

Стилизация приложения

Gifted Chat предлагает готовый дизайн, но его легко кастомизировать. Например, так можно изменить цветовое оформление:

<GiftedChat
  renderBubble={props => {
    return (
      <Bubble
        {...props}
        wrapperStyle={{
          right: {
            backgroundColor: '#2196F3'
          },
          left: {
            backgroundColor: '#e3e3e3'
          }
        }}
      />
    );
  }}
  {...otherProps}
/>

Используя пропсы Gifted Chat, можно изменять аватарки, сообщения, поле ввода, кнопки, иконки вложений и так далее. Смотрите официальную документацию: https://github.com/FaridSafi/react-native-gifted-chat

Особенности синхронизации и оптимизации

Работая в реальном времени, важно помнить о нескольких моментах:

  • Очень быстрый ввод текста может приводить к конкуренции между отправкой сообщения и обновлением UI. Можно добавить небольшую задержку (debounce) на отправку, если пользователь печатает сверхбыстро.
  • Firestore автоматически сортирует данные по времени. Для очень крупных чатов используйте пагинацию (пропсы минус limit/startAfter в запросах).
  • Не забывайте про обработку ошибок при потере соединения. Firebase сообщает о статусе соединения, можно отображать иконку статуса.

Хранение и обработка медиафайлов

В большинстве современных чатов пользователи обмениваются не только текстом, но и изображениями, видео, стикерами. Для передачи файлов воспользуйтесь Firebase Storage:

  1. Добавьте библиотеку загрузки файлов, например, react-native-image-picker.
  2. Получите путь к файлу, отправьте его на Firebase Storage.
  3. Сохраните ссылку на файл в Firestore как часть сообщения.

Пример добавления изображения в сообщение из галереи:

import {launchImageLibrary} from 'react-native-image-picker';
import { getStorage, ref, uploadBytes, getDownloadURL } from 'firebase/storage';

const storage = getStorage();

const pickImageAndSend = async () => {
  // Открываем галерею
  const result = await launchImageLibrary({mediaType: 'photo'});
  if (result.assets && result.assets.length) {
    const asset = result.assets[0];
    const response = await fetch(asset.uri);
    const blob = await response.blob();

    const storageRef = ref(storage, `images/${Date.now()}`);
    await uploadBytes(storageRef, blob);

    const imageUrl = await getDownloadURL(storageRef);

    // Отправляете сообщение с image: imageUrl
    await addDoc(collection(db, 'messages'), {
      text: '',
      createdAt: new Date(),
      user,
      image: imageUrl,
    });
  }
};

Gifted Chat позволяет выводить изображения, если сообщению добавить поле image с публичным URL.

Расширение и кастомизация

Вы можете доработать вашу версию чата:

  • Добавлять приватные/групповые чаты (схема коллекции Firestore, где у каждого чата есть свой id и коллекция сообщений).
  • Добавлять "просмотрено/не прочитано", индикаторы набора текста.
  • Внедрять push-уведомления через Firebase Cloud Messaging.
  • Искать сообщения, добавлять фильтры.

Тестирование и отладка

  • Используйте логирование внутри обработчиков (console.log) для отслеживания отправки и получения сообщений.
  • Проверьте работу приложения на обоих платформах (Android/iOS), так как работа с хранением, галереей и клавиатурой может отличаться.
  • Проверьте регистрацию новых пользователей, повторную авторизацию и поведение приложения без соединения.

Советы по безопасности и конфиденциальности

  1. Ограничьте публичный доступ к Firestore: настройте правила безопасности так, чтобы только авторизованные пользователи имели доступ к сообщениям.
  2. Не храните пароли в приложении.
  3. Не отправляйте приватные ключи приложения в коде (используйте хранение секретов или переменные окружения).
  4. Добавьте обработку состояния "offline" и синхронизацию сообщений после подключения.

Итоги

Теперь вы знаете, как создать собственное чат-приложение на React Native: от создания проекта до реализации реального обмена сообщениями и подключения к облаку. Используя инструменты вроде Gifted Chat и Firebase, даже базовая версия получится достаточно удобной и быстрой. Дальнейшее развитие функциональности (отправка файлов, групповые чаты, уведомления) — следующий шаг для вашего проекта.

Чат - это всегда отличный пример сложного приложения. Не стоит забывать, что нужно уметь создавать UI, настраивать навигацию и работать с разными API. На нашем курсе React Native и Expo Router вы найдете все необходимые знания для освоения React Native разработки. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в мир React Native прямо сегодня.

Частозадаваемые технические вопросы по теме статьи и ответы на них

Как реализовать функцию удаления сообщений в чате?

Чтобы добавить удаление сообщений, используйте метод deleteDoc из Firestore. Запросите id сообщения (обычно это doc.id), и вызовите: js import { deleteDoc, doc } from 'firebase/firestore'; // Удаляем сообщение по id await deleteDoc(doc(db, 'messages', messageId)); В самом интерфейсе добавьте кнопку удаления рядом с вашим сообщением.

Как авторизовать пользователей через Google, а не email и password?

Для этого используйте пакет @react-native-google-signin/google-signin и авторизацию в Firebase по внешнему токену. Настройте проект в консоли Firebase, получите WebClientID, следуйте инструкции пакета, используйте метод signInWithCredential.

Как оптимизировать загрузку сообщений для чатов с большим количеством данных?

Используйте пагинацию: в запросах Firestore передавайте параметры limit и startAfter, чтобы загружать ограниченную порцию сообщений при скролле вверх. Это уменьшит количество данных и ускорит рендер.

Почему возникает ошибка при сборке на Android, связанная с Multidex?

При большом количестве зависимостей можно получить ошибку и превышение лимита методов DEX. В файле android/app/build.gradle установите: multiDexEnabled true И добавьте зависимость: implementation 'androidx.multidex:multidex:2.0.1'

Как реализовать push-уведомления для новых сообщений?

Вам понадобится @react-native-firebase/messaging для регистрации устройства. После этого через облачные функции Firebase отправляйте сообщение в FCM каждому получателю при появлении нового сообщения в Firestore.

Стрелочка влевоГайд по структуре React Native проектовКак собрать React Native приложениеСтрелочка вправо

Постройте личный план изучения React-native до уровня Middle — бесплатно!

React-native — часть карты развития Mobile

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по React-native

Работа со ScrollView в React NativeРабота с видео в React NativeКак реализовать аудиоплеер на React NativeНастройка и использование input и textinput в React NativeИнтеграция видео плеера в приложение на React NativeИспользование выпадающих списков в React NativeСоздание и настройка native module на React NativeКак создать модальные окна в React NativeРабота с изображениями в React NativeОтображение списков данных в React NativeГайд по файловой системе в React NativeИнтеграция камеры в приложение на React NativeСоздание интерактивных кнопок в React Native
Как использовать векторные иконки в React Native5 популярных библиотек UI компонентов React NativeСоздание и использование tabs в React NativeРуководство по стилизации компонентов в React NativeОптимизация переходов между экранами в React NativeАдаптация safe area context на React NativeОбзор библиотек для навигации в React NativeСоздание сложных анимаций (reanimated) на React NativeИспользование библиотеки стилей Paper в React NativeРуководство по navigation в React NativeОптимизация отображения списков в React NativeКак реализовать linking на React NativeГайд по UI-китам для React NativeГде искать elements для приложения на React NativeРабота с цветами в React Native
Открыть базу знаний

Лучшие курсы по теме

изображение курса

React Native и Expo Router

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Основы JavaScript

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий