Как создать простой чат на React с Firebase

Когда вы в следующий раз будете пользоваться WhatsApp или другим мессенджером, задумайтесь: как именно доставляются сообщения почти мгновенно? Создание упрощённого чат-приложения — отличный способ понять основные механики: аутентификация, хранение сообщений, получение обновлений в реальном времени и отображение UI. В этой инструкции мы используем Firebase, чтобы пропустить настройку собственного сервера и быстро получить рабочий прототип.
Кому это полезно
- Фронтенд-разработчикам, которые хотят добавить реальный чат в приложение.
- Разработчикам, которые знакомы с React и хотят освоить Firestore и Firebase Auth.
- Тем, кто хочет быстрее прототипировать без DevOps.
Коротко о Firebase и Firestore
Firebase — облачная платформа для разработчиков от Google. Она предоставляет готовые backend-сервисы: аутентификацию, базу данных в реальном времени (Realtime Database), документную базу Firestore, хостинг, функции (Cloud Functions) и др.
Firestore — это NoSQL документная база данных с моделью «коллекции → документы». Она оптимизирована для реального времени и оффлайн-режима в клиентах.
Важно: Firestore — не реляционная СУБД. Для сложных транзакций и сложных агрегаций придётся пересмотреть модель данных.
Что будет в репозитории
- Простая структура на React (Create React App / Vite подойдёт).
- firebase-config.js: инициализация Firebase, Firestore и провайдера Google.
- components/SignIn.js — вход через Google (signInWithPopup).
- components/Chat.js — отображение последних N сообщений и кнопка Sign Out.
- components/SendMessage.js — форма отправки сообщения (addDoc).
Ниже — подробные шаги и объяснения.
1. Создайте проект в Firebase и зарегистрируйте веб-приложение
- Зарегистрируйтесь в Firebase и нажмите Create Project.
- На странице проекта нажмите значок «код» и зарегистрируйте веб-приложение — это даст конфигурацию SDK.
Запишите конфигурацию (apiKey, authDomain, projectId и пр.) — она понадобится в файле firebase-config.js.
Подсказка: для разработки используйте .env файлы (REACTAPP*) и не коммитьте секреты.
2. Установка зависимостей в React-проекте
Создайте React-приложение (Create React App / Vite). Затем установите Firebase и вспомогательную библиотеку:
npm install firebase react-firebase-hooksreact-firebase-hooks упрощает подписку на состояние аутентификации и данные Firestore.
3. Конфигурирование Firebase в приложении
Создайте src/firebase-config.js и вставьте туда конфигурацию, полученную из консоли Firebase.
import { initializeApp } from "firebase/app";
import { getFirestore } from '@firebase/firestore';
import { getAuth, GoogleAuthProvider } from "firebase/auth";
const firebaseConfig = {
apiKey: "API_KEY",
authDomain: "authDomain",
projectId: "project ID",
storageBucket: "storage Bucket",
messagingSenderId: "messanging sender ID",
appId: "App ID"
};
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
const auth = getAuth(app);
const provider = new GoogleAuthProvider();
export { db, auth, provider };Пояснение: initializeApp инициализирует SDK, getFirestore даёт клиент для работы с документной базой, getAuth управляет аутентификацией, а GoogleAuthProvider заранее готов к OAuth через Google.
4. Создайте базу данных Firestore и настройте правила (разработка)
В консоли Firebase в разделе Firestore нажмите Create database. Выберите режим (начните в тестовом режиме для разработки, но затем обязательно ужесточите правила).
Выберите регион и, при необходимости, режим. В тестовом режиме правила могут выглядеть так:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}Этот режим подходит только для локальной разработки и прототипов.
Для быстрой проверки можно создать коллекцию messages и добавить несколько документов вручную.
Важно: перед деплоем обязательно заменить allow read, write: if true на правила, проверяющие uid пользователя.
5. Настройка провайдера аутентификации (Google)
В консоли Firebase перейдите в Authentication → Sign-in method и включите Google. Укажите контактный email проекта.
6. Компонент SignIn — вход через Google
Создайте src/components/SignIn.js:
import React from 'react';
import { signInWithPopup } from "firebase/auth";
import { auth, provider } from '../firebase-config';
function SignIn() {
const signInWithGoogle = () => {
signInWithPopup(auth, provider);
};
return (
);
}
export default SignIn;Примечание: можно расширить обработку ошибок и показать индикатор загрузки в момент signInWithPopup.
7. Компонент Chat — отображение сообщений в реальном времени
Создайте src/components/Chat.js:
import React, { useState, useEffect } from 'react';
import { db, auth } from '../firebase-config';
import SendMessage from './SendMessage';
import { collection, query, limit, orderBy, onSnapshot } from "firebase/firestore";
function Chat() {
const [messages, setMessages] = useState([]);
const user = auth.currentUser;
useEffect(() => {
const q = query(
collection(db, "messages"),
orderBy("createdAt"),
limit(50)
);
const unsubscribe = onSnapshot(q, (querySnapshot) => {
const msgs = [];
querySnapshot.forEach((doc) => {
msgs.push({ ...doc.data(), id: doc.id });
});
setMessages(msgs);
});
return () => unsubscribe();
}, []);
return (
{messages && messages.map((message) => (
{message.text}
))}
);
}
export default Chat;Разбор ключевых моментов:
- onSnapshot подписывается на изменения и возвращает функцию отписки — её нужно вызвать при размонтировании.
- Мы получаем только 50 последних сообщений; по желанию измените limit.
- Для определения, какое сообщение своё, сравниваем message.uid и auth.currentUser.uid.
8. Компонент SendMessage — отправка сообщений
Создайте src/components/SendMessage.js:
import React, { useState } from 'react';
import { db, auth } from '../firebase-config';
import { collection, addDoc, serverTimestamp } from "firebase/firestore";
function SendMessage() {
const [msg, setMsg] = useState('');
const messagesRef = collection(db, "messages");
const sendMsg = async (e) => {
e && e.preventDefault && e.preventDefault();
if (!msg) return;
const { uid, photoURL } = auth.currentUser;
await addDoc(messagesRef, {
text: msg,
createdAt: serverTimestamp(),
uid: uid,
photoURL: photoURL
});
setMsg('');
};
return (
);
}
export default SendMessage;Заметки:
- serverTimestamp() гарантирует, что время будет установлено сервером, а не клиентом.
- Нельзя полностью полагаться на client-side правила безопасности — проверяйте правила в Firestore.
9. Подключение компонентов в App.js
В src/App.js импортируйте и условно рендерьте компоненты в зависимости от статуса аутентификации:
import Chat from './components/Chat';
import SignIn from './components/SignIn';
import { auth } from './firebase-config.js';
import { useAuthState } from 'react-firebase-hooks/auth';
function App() {
const [user] = useAuthState(auth);
return (
<>
{user ? : }
>
);
}
export default App;Запустите dev-сервер (npm start / npm run dev) и откройте приложение в браузере.
Безопасность и правила продакшена
Important: никогда не оставляйте правила Firestore в режиме “if true” на проде. Минимальные рекомендации:
- Разрешать запись только аутентифицированным пользователям: allow write: if request.auth != null;
- При необходимости проверять соответствие uid в документе и текущего пользователя.
Пример: запрет записи чужих uid и защита полей createdAt
service cloud.firestore {
match /databases/{database}/documents {
match /messages/{messageId} {
allow create: if request.auth != null && request.resource.data.uid == request.auth.uid
&& request.resource.data.keys().hasOnly(['text','createdAt','uid','photoURL']);
allow read: if true;
}
}
}Конфиденциальность и соответствие GDPR
- Firebase хранит метаданные в США/регионе, укажите регион хранилища при создании проекта.
- Для соответствия GDPR: информируйте пользователей об использовании внешнего провайдера, получите согласие, если нужно хранить персональные данные.
- Для удаления данных реализуйте кнопку удаления сообщений и соответствующие серверные правила.
Когда Firebase не подходит — ограничения и альтернативы
Когда Firebase/Firestore могут оказаться не лучшим выбором:
- Если нужна сложная реляционная логика и сложные JOIN-выборки — реляционная база может быть удобнее.
- Высокая стоимость при большом объёме операций (Firestore тарифицирует чтения/записи/запросы).
- Требуется низкая латентность в специфичных регионах/локально критичные задержки.
Альтернативы:
- Socket.io + собственный бекенд (Node.js) — полный контроль и оптимизация трафика.
- Supabase (Postgres + realtime) — похож на Firebase, но на основе Postgres.
- AWS Amplify + AppSync (GraphQL) — интеграция с экосистемой AWS.
Тесты и критерии приёмки
Критерии приёмки минимального чата:
- Пользователь может войти через Google.
- После входа видны последние 50 сообщений, отсортированные по времени.
- Пользователь может отправить сообщение — оно появляется без перезагрузки.
- Кнопка «Выйти» завершает сессию.
Примеры тестов:
- E2E: войти, отправить сообщение, проверить появление текста у всех подключённых клиентов.
- Unit: функция отправки вызывает addDoc с нужными полями; мокировать Firestore.
Рекомендации по масштабированию
- Пагинация: используйте курсоры (startAfter) для подгрузки истории.
- Шардирование коллекций: при высоком приросте сообщений разделяйте коллекцию по чатам/комнатам.
- Индексирование: добавляйте индексы для часто используемых запросов в Firestore.
Ментальные модели и чеклисты (для команды)
Ментальная модель: приложения реального времени состоят из трёх слоёв — аутентификация (кто), хранение состояния (что) и транспорт/подписки (когда/как). Если хотя бы один слой ненадёжный — пользовательский опыт разрушится.
Чеклист разработчика:
- Проект Firebase создан и конфигурация в .env
- Firestore создан и коллекция messages доступна для разработки
- Google OAuth включён
- Компоненты SignIn, Chat, SendMessage добавлены
- Правила безопасности настроены для продакшена
- Тесты на отправку/получение сообщений написаны
Роли и обязанности:
- DevOps: настроить проект в Firebase, выбрать регион, настроить billing.
- Backend/Lead: написать строгие правила безопасности в Firestore.
- Frontend: реализовать UI и обработку ошибок.
Мини-методология развертывания (SOP)
- Локальная разработка: .env.local с конфигом Firebase (только для dev).
- Разверните проект на staging, включите реальные правила безопасности.
- Тесты E2E на staging с тестовыми аккаунтами Google.
- Перевод в production: изменить правила, включить биллинг, мониторинг.
Отладка — распространённые ошибки
- Ошибка: auth.currentUser === null сразу после входа. Причина: асинхронная инициализация — используйте useAuthState или слушатель onAuthStateChanged.
- Ошибка: messages не сортируются — проверьте поле createdAt; если оно null, серверный timestamp не успел записаться.
- Ошибка: превышение квот Firestore — исследуйте количество чтений (каждый onSnapshot может читать много документов).
Факто-бокс
- Тип данных: Firestore — NoSQL (документы JSON-подобные).
- Транзакции: поддерживаются, но сложные агрегаты лучше выполнять на сервере.
- Подписки: onSnapshot предоставляет обновления в реальном времени.
Короткое резюме
- Firebase позволяет быстро прототипировать чат без отдельного бэкенда.
- Используйте серверные метки времени и правила безопасности для продакшена.
- Рассмотрите альтернативы при высоких нагрузках или сложной модели данных.
Важно: перед публикацией убедитесь, что правила доступа в Firestore настроены корректно и вы проинформировали пользователей о хранении их персональных данных.
Краткое объявление для команды (100–200 слов)
Добавили прототип чата на React с использованием Firebase (Firestore + Google Auth). В репозитории есть компоненты SignIn, Chat и SendMessage и файлы для быстрой настройки (firebase-config.js). Проект подходит для быстрых прототипов и внутренних инструментов; перед развёртыванием нужно обновить правила безопасности Firestore и проверить соответствие политике конфиденциальности.
Похожие материалы
Сворачивание разделов в Word — как и зачем
Как оставаться мобильным без смартфона
Перекрёстные ссылки в Microsoft Word
Тени в PowerPoint: как добавить drop shadow