EN RU

@demondehellis

Рассказываю о технологиях и программировании.

Firebase и облачные функции

Firebase — прикольная штука, которая меня по-настоящему вдохновляет. Представь, можно не держать свой сервер, а просто запускать код по запросу. Или, например, безопасно писать в базу прямо из JS (да, Карл). Огромная гугловая инфраструктура под боком — хочешь, подключай файловое хранилище, хочешь нейронку, хочешь авторизацию.

Всё это уже упаковано так, что в несколько строк на питоне можно собрать рабочий прототип, и при этом кода будет в разы меньше, чем если бы ты держал свой сервер. В моём случае, я пока не заплатил за Firebase ни копейки, т.к. у него довольно большие бесплатные квоты. В общем, халява и киберпанк. Для своих пет-проджектов — супер.

Порог входа

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

В чём прикол? Облачные функции и триггеры

Главная магия Firebase — это облачные функции и триггеры на события. Пишешь себе скрипт на питоне, например, функцию, которая делает запрос к RSS и парсит элементы:

import feedparser
from firebase_functions import https_fn

@https_fn.on_request()
def parse_rss(req: https_fn.Request) -> https_fn.Response:
    feed = feedparser.parse('https://news.com/rss')
    items = [{'title': entry.title, 'link': entry.link} for entry in feed.entries]
    return https_fn.Response(items)

Добавляешь к функции специальный декоратор @https_fn.on_request(), деплоишь одной консольной командой:

firebase deploy --only functions:parse_rss

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

А можно использовать другой декоратор и запускать функцию по расписанию, типа как по крону:

from firebase_functions import scheduler_fn

@scheduler_fn.on_schedule(schedule="every 24 hours")
def daily_rss_check(event: scheduler_fn.ScheduledEvent) -> None:
    # Твой код, который будет выполняться раз в сутки
    pass

И никакого сервера; код крутится в облаке и скейлится под любые нагрузки — это все на базе гугловой инфраструктуры, на которой работают и все прочие их сервисы.

Магия с базой данных

Захотел, например, сохранять эти RSS в базу? Пишешь две строчки кода с подключением Firestore (это NoSQL БД от Firebase). Никаких миграций не надо, просто кидаешь туда любой массив/объект в любой структуре:

from firebase_admin import initialize_app, firestore
initialize_app()

# Сохраняем данные в базу
firestore.Client().collection('rss_items').add({
    'title': 'Новая статья',
    'url': 'https://example.com/article',
    'date': firestore.SERVER_TIMESTAMP
})

И вот оно уже в базе. Не нужно париться о схеме данных. Хочешь добавить новое поле? Просто добавь его в данные, и всё.

Событийная архитектура

А теперь самое интересное — триггеры. Допустим, ты хочешь, чтобы для каждого нового RSS-элемента ещё и какая-то специальная логика выполнялась, например, переслать его в телеграм.

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

В случае с Firebase можно использовать событие типа “элемент добавлен в базу” и запускать свой код по этому событию:

from firebase_functions import firestore_fn

@firestore_fn.on_document_created(document="rss_items/{itemId}")
def send_to_telegram(event: firestore_fn.Event[firestore_fn.DocumentSnapshot]) -> None:
    # Получаем данные из добавленного документа
    item_data = event.data.to_dict()
    
    # Отправляем в телеграм
    telegram_message = f"Новая статья: {item_data['title']}\n{item_data['url']}"
    send_telegram_message(telegram_message) # тут твой код для отправки сообщения

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

Теперь логика разделена, и так гораздо удобнее: никаких проверок и поиска по базе не надо. Если элемент уже в базе есть, то триггер не запустится (ну или можно сделать триггер на обновление, если нужно).

Что ещё прикольного

Помимо функций и базы данных, в Firebase есть:

Пока что мне нравится этот опыт — меньше возни с инфраструктурой, больше времени на саму разработку.


Еще всякое интересное