Всем доброго дня! Комментарии к моей предыдущей статье о том, как я развиваю свой pet-проект, а также различные законы, подразумевающие локализацию персональных данных на серверах, размещенных на территории РФ (в частности Федеральный закон от 21.07.2014 № 242-ФЗ «О внесении изменений в отдельные законодательные акты Российской Федерации в части уточнения порядка обработки персональных данных в информационно-телекоммуникационных сетях»), озадачили меня идеей постепенной миграции всех данных приложения из Google Firebase в на сервер внутри РФ.

Возможно вы уже столкнулись с этой проблемой после прекращения возможности привязки карт РФ к платежному аккаунт Google Cloud Platform в 2022, либо вы задумались о миграции в целях контроля над данными или уменьшение затрат на облачное хранилище.

Я отдал предпочтение opensource-сервису Supabase, который легко разворачивается в Docker на сервере, однако, наверняка есть и аналогичные BaaS, поэтому буду рад вашим комментариям к данной статье.

Предисловие

Для начала я хочу обзорно пройтись по сравнению двух сервисов, представляющих собой не только СУБД, а BaaS (backend as a service), основное внимание заострю на работе с данными, постараясь сравнить их функционал, производительность и простоту использования.

Туториал предполагает наличие некоторых данных в БД Firebase, которые мы будем переносить в Supabase. Помимо действий, необходимых для переноса данных, приведу также примеры кода обработки получения, обновления и удаления данных в Google Firebase Realtime Database и Supabase Realtime Database на JavaScript.

Стоит сразу сделать оговорку, что Realtime Database от Firebase - это облачная БД для хранения и синхронизации данных в реальном времени, в то время как БД от Supabase хоть и является её аналогом, но позволяет хостить базу данных самостоятельно ("под капотом" у Supabase располагается объектно-реляционная СУБД PostgreSQL).

Установка и настройка Supabase в Docker

Первым делом нам понадобится установить и произвести первоначальную настройку self-hosted Supabase. Проще всего будет следовать официальной документации Supabase по установке и настройке сервера. Этот процесс включает в себя установку Docker, получение и запуск образа Supabase, а затем настройку окружения и доступа к базе данных PostgreSQL.

В результате установки, для подключения к базе данных, нам потребуется URL, по которому размещен сервер, а также секретный ключ для подключения к API Supabase.

Экспорт имеющихся данных из Firebase

Firebase позволяет выгрузить текущее состояние данных из в формате JSON при помощи интерфейса:

Возможность экспорта в JSON доступна в разделе Realtime Database в консоли Google Firebase
Возможность экспорта в JSON доступна в разделе Realtime Database в консоли Google Firebase

Однако, все же наиболее оптимальным способом экспорта данных из Firebase является использование встроенного инструмента в виде Firebase CLI (npm-пакет firebase-tools), который помимо основных операций над данными позволяет произвести экспорт данных в формате JSON:

firebase database:export --project <ID_проекта> <файл_экспорта.json>

Сохраните файл, полученный в результате экспорта, он пригодится нам в следующих шагах.

Импорт данных в Supabase Realtime Database

Теперь нам необходимо импортировать экспортированные данные (файл, полученный на предыдущем этапе) в Supabase Realtime Database. Для этого вы можете воспользоваться Supabase JS SDK или использовать HTTP API по инструкциям из документации Supabase.

Supabase JS SDK позволяет нам на уровне скрипта описать алгоритм импорта данных, а затем запустить этот скрипт на вашем сервере. Создадим файл import-data.js со следующим содержимым:

import { createClient } from '@supabase/supabase-js';

const supabaseUrl = 'https://your-hosted-supabase-url.com';
const supabaseKey = 'your-supabase-key';
const supabase = createClient(supabaseUrl, supabaseKey);

const data = require('./целевой_файл.json');

async function importData() {
  let { data, error } = await supabase.from('your_table').insert(data);
  if (error) {
    console.error('Ошибка импорта данных:', error);
  } else {
    console.log('Данные успешно импортированы');
  }
}

importData();

Для импорта данных нам потребуется разместить в одной директории на сервере оба файла - JSON с данными из Firebase и import-data.js, а затем произвести запуск JS-файла при помощи NodeJS:

node ./import-data.js

Альтернативным способом импорта данных будет использование HTTP API Supabase. Насколько мне удалось поработать с этим проектом, Supabase предоставляет RESTful API с использованием PostgREST. Это очень тонкий слой API поверх Postgres, который позволяет совершать любые CRUD-операции по URL вида:

https://<project_ref>.supabase.co/rest/v1/

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

Обращение к БД и основные операции над данными

Все примеры привожу на JS для простоты понимания, а также потому что сам его использую в проектах. Если вы используете какой-либо другой ЯП в ваших проектах, то логика обращения к БД будет идентична.

Примеры кода приведены без написания конкретных методов под функционал приложений, а лишь сами обращения к БД как источникам данных. При желании вы можете модифицировать их как вам будет удобно.

Получение данных из Firebase Realtime Database:

const database = firebase.database();
const ref = database.ref('users');

ref.once('value', (snapshot) => {
  snapshot.forEach((childSnapshot) => {
    const childData = childSnapshot.val();
    console.log(childData);
  });
});

Получение данных из Supabase Realtime Database:

const { data, error } = await supabase
  .from('users')
  .select('*');
console.log(data);

Обновление данных Firebase Realtime Database:

const database = firebase.database();
const ref = database.ref('users/uid1');

ref.update({
  fullName: 'John Doe',
  email: 'john.doe@example.com'
});

Обновление Supabase Realtime Database:

const { data, error } = await supabase
  .from('users')
  .update({email: 'newemail@example.com'})
  .eq('id', 'uid1');

Физическое удаление данных из Firebase Realtime Database:

const database = firebase.database();
const ref = database.ref('users/uid1');
ref.remove();

Физическое удаление данных из Supabase Realtime Database:

const { data, error } = await supabase
  .from('users')
  .delete()
  .eq('id', 'uid1');

Обратите внимание на синтаксис обращений к БД Supabase - поскольку это решение использует PostgreSQL в качестве своего ядра базы данных, то все обращения к ней представляют собой некое подобие SQL-запросов с поддержкой реляционных структур данных, в отличие от представления данных в документальном или древовидном представлении в Firebase.

Данный туториал носит ознакомительный характер и дает общие рекомендации по переносу данных, тем не менее надеюсь он поможет вам при осуществлении миграции. Буду рад почитать в комментариях ваш опыт по переезду с Firebase и прочих сервисов Google Cloud.

Комментарии (2)


  1. chuikoffru
    03.12.2023 14:47

    Какие ресурсы серверные вы закладывали на self-host supabase? Я локально пробовал разворачивать, и мне показалось чисто на старте 2Гб оперативы минимум для развертки нужно. Куча сервисов. Один из сервисов не завелся из коробки. Решил отложить до лучших времен.


    1. yuryweiland Автор
      03.12.2023 14:47

      На данный момент у меня развернут supabase на VDS с характеристиками:

      CPU: AMD EPYC™ 2 vCPU core
      RAM: 8 GB
      DISK: 64 GB NVMe

      По потреблению ресурсов, с учетом что там еще несколько мелочей крутится, htop показывает использование порядка 2,6Гб ОЗУ, но к счастью в моем случае все сервисы развернулись без особых проблем (разве что дополнительно настроил ротацию логов в самом Docker чтобы логи не съедали дисковое пространство со временем)