Это шаг за шагом для создания простого чат-приложения React Native с использованием компонента GiftedChat с базой данных Firebase Realtime и Firebase Storage. Firebase - это облачный сервис Google, который предоставляет нам уровень бесплатного пользования (Spark) до 100 одновременных пользователей и хранилище файлов размером 1 ГБ. Хранилище позволяет нам загружать изображение в качестве аватара пользователя, которое может отображать компонент GiftedChat.

Мы будем использовать React Native с Expo на основе этого учебника с изменениями, чтобы использовать регистрацию по электронной почте, а не анонимно, и более подробную информацию о настройке Firebase. Также мы добавляем возможность загружать изображения в качестве аватара.

Наше приложение представляет собой простую программу чата, в которой пользователь может создать новый логин, используя адрес электронной почты. Новый пользователь может зарегистрироваться с уникальным адресом электронной почты. Если адрес электронной почты существует, регистрация не удалась. Пользователь также может загрузить изображение для создания собственного аватара. После того, как пользователь войдет в систему, пользователь увидит существующие сообщения и отправит новые сообщения. Новые сообщения будут опубликованы для других пользователей, вошедших в систему, точно так же, как групповой обмен сообщениями в режиме реального времени.

Firebase

Чтобы хранить и уведомлять других пользователей о сообщениях, мы используем базу данных Firebase в реальном времени. Firebase - это облачный сервис от Google, который обеспечивает аутентификацию, базы данных документов noSQL (в реальном времени и новый Cloud Firestore), хранилище и другие сервисы. Мы будем использовать только аутентификацию и базу данных и хранилище в реальном времени. База данных предоставляет возможность подписаться на события в реальном времени, когда данные добавляются или обновляются. В нашем случае использования, когда кто-то отправляет сообщение, мы добавляем его в базу данных, и другие пользователи, вошедшие в систему, могут получать уведомление о новом сообщении. Подробнее о том, как работает база данных Firebase в реальном времени, вы можете прочитать в quora.

Настройка Firebase

В Firebase есть бесплатный уровень, на котором мы можем использовать план Spark. Ограничение до 100 одновременных подключений. Этого достаточно для наших целей.

Зарегистрируйтесь и войдите в консоль firebase: https://console.firebase.google.com/

Создайте новый проект и введите название проекта.

Включите аутентификацию с использованием пароля электронной почты, нажав «Аутентификация», затем, «Метод входа», нажмите «Статус» для «Электронная почта / пароль» и установите переключатель «Включить» в положение «Вкл.». Затем нажмите «Сохранить».

Настройка базы данных

  • В левом меню выберите базу данных в левом меню, затем создайте новую базу данных.
  • Затем выберите базу данных реального времени, в соответствии с правилом измените чтение / запись на true:

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

Использование Expo Snack

Для кодирования нашего примера мы будем использовать Expo Snack, который позволяет нам писать и тестировать код на другом симуляторе или быстро использовать наши телефоны с помощью веб-браузера без каких-либо настроек.

Сначала зайдите на expo.io в своем любимом браузере и зарегистрируйтесь для получения бесплатной учетной записи. Затем под профилем нажмите СОЗДАТЬ НОВУЮ ЗАКУСКУ, чтобы начать кодирование.

Экран с редактором кода позволит вам писать код. Начнем с капризного сэндвич-шаблона.

Вы можете щелкнуть по названию и изменить его на любое понравившееся имя. Затем нажмите «Нажмите, чтобы играть», чтобы увидеть, как он работает в эмуляторе.

У вас есть возможность запустить это на своем телефоне. Это предпочтительный подход, чтобы увидеть, как он работает на устройстве. Но сначала вам нужно загрузить приложение Expo на свой телефон и войти в систему. Затем вы можете подключиться, нажав «Выполнить» и нажав на QR-код. Используйте приложение QR-кода для QR-кода с экрана и запустите его.

Давайте запустим код и посмотрим приложение. Если вы используете телефон, вы должны увидеть логотип Expo, а затем приложение. Это просто статичный экран, который выглядит вот так.

Начать кодирование

Давайте обновим структуру кода, чтобы мы могли добавить больше экранов и навигации.

Вот описание различных экранов. Эти файлы находятся в каталоге components:

Login.js: экран, позволяющий пользователю войти в систему с вводом адреса электронной почты и пароля.

CreateAccount.js: разрешить пользователю создать новую учетную запись. После создания учетной записи у пользователя есть возможность загрузить изображение в качестве аватара.

Chat.js: это одаренный компонент чата, который отображает сообщение чата и позволяет пользователю отправлять новые сообщения.

App.js будет навигатором переключателей.

Переименовать и обновить код

Переименуйте AssetExample.js в Chat.js в каталоге components.

  1. Щелкните каталог component, чтобы увидеть AssetExample.js (щелкните еще раз, если нет), наведите указатель мыши на AssetExample.js, чтобы увидеть три вертикальные точки, и щелкните по нему, затем выберите «Переименовать» во всплывающем меню. . Затем введите «Чат» и нажмите Enter.

2. Обновите класс до Chat в строке 4 следующим образом:

import { GiftedChat } from 'react-native-gifted-chat';

После того, как вы нажмете Enter, вы увидите сообщение в левом нижнем углу экрана с просьбой добавить пакет. Просто нажмите ДОБАВИТЬ. Это добавит пакет в ваш package.json.

import React from 'react';
import { GiftedChat } from 'react-native-gifted-chat';
export default class Chat extends React.Component {
  render() {
    return (
      <GiftedChat 
      />
    );
  }
}

3. Добавить новый экран: Войдите в систему
В разделе «Компонент» нажмите «+», чтобы добавить новый файл. Затем переименуйте «Untitled file.js» в Login.js.

4. Вставьте содержимое ниже:

import React from 'react';
import { Text, View, Button } from 'react-native';
export default class Login extends React.Component {
  render() {
    return (
      <View>
        <Text>My Login Screen</Text>
        <Button title="Navigate to Chat"
          onPress = {()=>this.props.navigation.navigate('Chat')}
        />
      </View>
    );
  }
}

5. Обновите App.js, чтобы использовать навигацию по стеку для маршрутизации экрана входа и чата.

import Login from './components/Login';
import Chat from './components/Chat';
// Import React Navigation
import { createStackNavigator } from 'react-navigation'
// Create the navigator
export default createStackNavigator({
  Login: Login,
  Chat: Chat,
});

Вы увидите предупреждающее сообщение ниже, просто нажмите ДОБАВИТЬ.

Если вы посмотрите на package.json, вы увидите что-то вроде этого:

{
  "dependencies": {
    "react-native-paper": "2.1.3",
    "react-native-gifted-chat": "0.4.3",
    "react-navigation": "2.18.2"
  }
}

6. Теперь проверьте навигацию и убедитесь, что вы видите экран.

Нажмите «Перейти к чату», вы должны увидеть экран, аналогичный показанному ниже. Когда вы введете сообщение, вы увидите кнопку «Отправить», как показано ниже.

Кнопка Отправить пока ничего не делает. Но над функционалом мы немного поработаем.

На этом этапе базовые экраны готовы для входа в систему. Итак, начнем с экрана входа в систему, но сначала получим информацию из базы данных Firebase и создадим тестового пользователя.

Настроить Firebase

Получите конфигурацию Firebase:

В обзоре проекта нажмите шестеренку, затем выберите «Настройки проекта».

Затем прокрутите вниз и нажмите «Добавить Firebase в свое веб-приложение», чтобы получить конфигурацию.

Скопируйте раздел конфигурации со значением apiKey до значения messageSenderId. Сохраните это для конфигурации Fire в следующем разделе.

Добавление нового пользователя вручную:

Перейдите в раздел «Аутентификация», затем «Пользователи» и нажмите «Добавить пользователя». Вы должны увидеть экран ниже. Затем введите адрес электронной почты и пароль и нажмите «Добавить пользователя».

Настройка Firebase

Создайте новый файл FirebaseSvc.js, выбрав App.js и щелкнув значок добавления файла. Затем назовите файл FirebaseSvc.js.

Добавьте приведенный ниже код в файл и замените ключи, которые вы только что скопировали из настроек Firebase.

import firebase from 'firebase';
class FirebaseSvc {
  constructor() {
    if (!firebase.apps.length) { //avoid re-initializing
      firebase.initializeApp({
        apiKey: "<your-api-key>",
        authDomain: "<your-auth-domain>",
        databaseURL: "https://<your-db-url>.firebaseio.com",
        projectId: "<your-project-id>",
        storageBucket: "<your-storage-bucket>.appspot.com",
        messagingSenderId: "<your-sender-id>"
      });
     }
  }
login = async(user, success_callback, failed_callback) => {
     await firebase.auth()
       .signInWithEmailAndPassword(user.email, user.password)
     .then(success_callback, failed_callback);
  }
}
const firebaseSvc = new FirebaseSvc();
export default firebaseSvc;

После ввода кода Expo знает, что мы используем firebase, поэтому вам будет предложено: Добавить firebase в package.json? Просто нажмите ДОБАВИТЬ.

Обновите Login.js, чтобы читать вводимые пользователем данные, устанавливать состояние и вызывать логин из класса firebase.

// add import
import firebaseSvc from '../FirebaseSvc';
// add state to store user input
state = {
  email: '[email protected]',
  password: 'test123',
};
// add login method to handle user press Login button
onPressLogin = async () => {
  const user = {
    email: this.state.email,
    password: this.state.password,
  };
  firebaseSvc.login(user, this.loginSuccess, this.loginFailed);
};
loginSuccess = () => {
  console.log('login successful, navigate to chat.');
  this.props.navigation.navigate('Chat', {
    name: this.state.name,
    email: this.state.email,
  });
};
loginFailed = () => {
  alert('Login failure. Please tried again.');
};
// methods to handle user input and update the state
onChangeTextEmail = email => this.setState({ email });
onChangeTextPassword = password => this.setState({ password });

Тестовый вход

Давайте пока проверим логин. Если бы мы должны были войти в систему, используя созданную учетную запись test99, мы должны автоматически перейти на экран чата. В противном случае мы сообщим, что наш логин недействителен. Когда мы запускаем приложение, мы должны увидеть этот экран.

Нажмите Login, и мы должны увидеть экран чата, как показано ниже. Если вы измените пароль на другой и снова нажмете «Войти», мы должны увидеть сообщение об ошибке.

Теперь мы готовы создать новую учетную запись для входа.

Создать новую учетную запись для входа

Используя метод входа по электронной почте / паролю, вы можете создать учетную запись, состоящую из displayName, электронной почты, пароля и аватара. Нам нужны displayName и avatar для отображения имени пользователя или изображения в сообщении чата.

Когда пользователь входит в систему, пользователь вводит только адрес электронной почты и пароль, поэтому нам нужно получить displayName и аватар из профиля входа. Функция создания учетной записи принимает только адрес электронной почты и пароль, поэтому мы можем использовать updateProfile для обновления displayName и аватара. Аватар - это URL-адрес изображения, которое мы сохранили в хранилище Firebase. Мы расскажем об этом в разделе загрузки изображений.

Чтобы создать учетную запись, мы используем функцию создания учетной записи createUserWithEmailAndPassword, которая принимает адрес электронной почты и пароль.

firebase.auth()
.createUserWithEmailAndPassword(user.email, user.password)

При успешном создании учетной записи мы используем updateProfile для обновления displayName или аватара. Теперь мы обновим user displayName следующим образом:

var userf = firebase.auth().currentUser;
userf.updateProfile({ displayName: user.name})

Давайте добавим метод createAccount в FirebaseSvc.js для создания нового входа.

createAccount = async (user) => {
  firebase.auth()
    .createUserWithEmailAndPassword(user.email, user.password)
  .then(function() {
    var userf = firebase.auth().currentUser;
    userf.updateProfile({ displayName: user.name})
    .then(function() {
      alert("User " + user.name + " was created successfully.");
    }, function(error) {
      console.warn("Error update displayName.");
    });
  }, function(error) {
    console.error("got error:" + error.message);
    alert("Create account failed.");
  });
}

Создайте новый экран, чтобы позволить пользователю создать учетную запись, скопировав Login.js. Наведите указатель мыши на Login.js, щелкните три вертикальные точки и выберите «Дублировать». Назовите новый файл CreateAccount.js. Затем обновите имя класса и измените метод входа в систему с помощью создания учетной записи, как показано ниже.

Чтобы выделить часть кода, когда пользователь нажимает «Создать учетную запись», мы вызываем createAccount в firebaseSvc. Мы рассмотрим это ниже. Когда пользователь нажимает кнопку загрузки, нам нужно разрешение, чтобы открыть CAMERA_ROLL, затем попросить пользователя выбрать и масштабировать изображение до максимальной ширины 150 пикселей. Затем вызовите uploadImage в файле firebaseSvc. Давайте рассмотрим изменения firebaseSvc. Для createAccount мы используем метод createUserWithEmailAndPassword из firebase.

createAccount = async (user) => {
  firebase.auth()
  .createUserWithEmailAndPassword(user.email, user.password)
  .then(function() {
    var userf = firebase.auth().currentUser;
    userf.updateProfile({ displayName: user.name})
    .then(function() {
      alert("User was created successfully.");
    }, function(error) {
      console.warn("Error update displayName.");
    });
  }, function(error) {
    alert("Create account failed. Error: "+error.message);
  });
}

Добавление аватара

Чтобы добавить аватар, вам нужно будет получить URL-адрес изображения пользователя. Мы позволим пользователю загружать изображение из своей фото-библиотеки или камеры. Изображение будет загружено в Firebase Storage, который представляет собой файловое хранилище в облаке.

Чтобы загрузить изображение, мы используем метод put для переданного URI. URI выглядит примерно так: file: /// Users / sim1 / Library /… ImagePicker /… 0E2929B .jpg. Подробный метод uploadImage в firebaseSvc.js приведен ниже:

uploadImage = async uri => {
  try {
    const response = await fetch(uri);
    const blob = await response.blob();
    const ref = firebase.storage().ref('avatar').child(uuid.v4());
    const task = ref.put(blob);
    return new Promise((resolve, reject) => {
      task.on('state_changed', () => { }, reject, 
        () => resolve(task.snapshot.downloadURL));
    });
  } catch (err) {
    console.log('uploadImage error: ' + err.message); 
  }
}

Когда пользователь успешно загружает изображение, state.avatar обновляется. Затем вызовите updateAvatar, чтобы обновить профиль пользователя с URL-адресом. UpdateAvatar аналогичен обновлению отображаемого имени пользователя. Мы не будем здесь останавливаться на деталях. И displayName, и аватар используются в компоненте GiftedChat. Если аватар недоступен, он использует displayName для создания инициала для пользователя.

В App.js нам также нужно добавить этот экран к маршруту навигации.

import CreateAccount from './components/Chat';
...
export default createStackNavigator({
  Login: Login,
  Chat: Chat,
  CreateAccount: CreateAccount, // add new route
});

Финальный тест

Мы готовы протестировать создание учетной записи и загрузку изображения. Запустите приложение, затем нажмите «Перейти к созданию учетной записи», затем измените адрес электронной почты и имя, нажмите «Создать учетную запись». Если электронное письмо существует, оно не сработает, иначе будет указано, что учетная запись создана успешно.

Теперь мы можем загрузить изображение, нажав «Загрузить изображение аватара». Впервые он запросит разрешение на изображение. Щелкните ОК, чтобы начать выбор изображения.

Выберите изображение и нажмите «Выбрать». Теперь вы должны быть предупреждены, что изображение успешно.

Убедитесь, что изображение сохранено в хранилище Firebase, перейдя в консоль Firebase. Обратите внимание, что вывод изображения в журнале вывода:

Файл находится в папке аватара с именем, начинающимся с 983d9217. Обратите внимание, что URL-адрес также содержит токен для доступа к файлу.

Обновить сообщение чата

Мы готовы показать обновление сообщения чата. Компонент Chat будет привязан к this.state.message, который является массивом объектов.

В Chat.js нам нужна информация о пользователе для создания сообщения. Мы можем использовать опору, которая передается с экрана входа в систему. Создаем массив сообщений в состоянии. Когда состояние обновится, и GiftedChat обновится.

Сообщения обновляются, когда компонент чата монтируется путем вызова метода firebaseSvc to refOn.

componentDidMount() {
  firebaseSvc.refOn(message => 
    this.setState(previousState => ({
      messages: GiftedChat.append(previousState.messages, message),
      })
    )
  );
}

В методе refOn внутри firebaseSvc следующее:

refOn = callback => {
  this.ref
    .limitToLast(20)
    .on('child_added', snapshot => callback(this.parse(snapshot)));
}

Метод синтаксического анализа берет данные снимка и создает сообщение:

parse = snapshot => {
  const { timestamp: numberStamp, text, user } = snapshot.val();
  const { key: _id } = snapshot;
  const timestamp = new Date(numberStamp);
  const message = {_id, timestamp, text, user};
  return message;
};

Чтобы отправить сообщение, мы вызываем метод send из компонента GiftedChat в свойстве onSend как таковой: onSend = {firebaseSvc.send}

Метод отправки в Firebase.js:

send = messages => {
  for (let i = 0; i < messages.length; i++) {
    const { text, user } = messages[i];
    const message = {text, user, createdAt: this.timestamp, };
    this.ref.push(message);
  }
};

Тестовый чат

Мы готовы к работе. Давайте протестируем логин и отправим сообщение. По мере ввода сообщения кнопка «Отправить» будет активна. После нажатия кнопки «Отправить» сообщение должно появиться справа.

Проверьте сообщение в консоли Firebase

В консоли Firebase выберите базу данных в левом меню, затем База данных в реальном времени.

Вы увидите сообщения, затем развернете объект и увидите подробную информацию о сообщении и пользователе.

Вот полный чат Chat.js.

Это оно. Вы видите полный код и можете попробовать этот код в репозитории здесь:

Https://snack.expo.io/@samauch/simple-chat-with-avatar

Спасибо за прочтение. См. Другой соответствующий учебник ниже.

использованная литература

  1. Https://blog.expo.io/how-to-build-a-chat-app-with-react-native-3ef8604ebb3c
  2. Https://appendto.com/2017/11/build-simple-chat-app-react-native-firebase/
  3. Https://github.com/CodeLinkIO/Firebase-Image-Upload-React-Native