Перейти к основному содержимому

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

Cloud Functions позволяют запускать код бэкенда в ответ на события, инициированные возможностями Firebase, и HTTPS-запросы. Например, вы хотите автоматически отправлять приветственное письмо пользователям при регистрации в приложении. Это можно реализовать с помощью Cloud Function, которая срабатывает на событие создания пользователя в Firebase Authentication.

Мы предоставляем возможность писать и развертывать Firebase Cloud Functions непосредственно в платформе. Благодаря интегрированному редактору кода написание JavaScript-функций облака происходит быстро и удобно. Каждая функция имеет настраиваемые шаблонные параметры, включая предустановленные essentials, такие как объем памяти, регион и тайм-аут.

примечание

Ознакомьтесь с интересными сценариями использования Cloud Functions.

Добавление Cloud Functions

Давайте разберем, как добавить Cloud Function, на примере создания логотипов на основе подсказок пользователя. Вот как это выглядит:

Cloud Function принимает ввод из виджета TextField и инициирует вызов API к image generation API. После получения URL изображения оно отображается в виджете Image.

Вот пошаговая инструкция по созданию такого примера:

  1. Добавьте переменные состояния страницы
  2. Создайте страницу
  3. Создайте и разверните Cloud Function
  4. Опционально: Добавьте пакет
  5. Запустите Cloud Function
  6. Опционально: Используйте результат Cloud Function
Перед началом
  • Убедитесь, что проект использует тарифный план Blaze в Firebase.
  • Выполните все шаги из раздела Настройка Firebase.

1. Добавьте переменные состояния страницы

Для этого примера вам потребуется настроить две переменные состояния страницы:

  1. generatingImage (Type: Boolean): Эта переменная используется для управления видимостью индикатора загрузки во время создания логотипа. Ее значение устанавливается в True перед началом вызова API и переключается в False после завершения генерации логотипа.
  2. logoImage (Type: ImagePath): Эта переменная используется для хранения сгенерированного изображения логотипа. После успешного вызова API полученный URL изображения сохраняется здесь, что позволяет отобразить логотип в виджете Image.

img_6.png

2. Создайте страницу

Добавьте страницу, которая позволит пользователям вводить подсказку. Чтобы ускорить процесс, вы можете добавить страницу из шаблона или использовать AI Page Gen. Вот страница, добавленная с помощью AI Page Gen, после некоторых изменений она выглядит так:

Также ознакомьтесь с тем, как создать макет страницы, если вы хотите построить страницу с нуля.

img_7.png

Несколько моментов, на которые стоит обратить внимание:

  • Мы используем виджет ConditionalBuilder для показа/скрытия индикатора загрузки в зависимости от переменной generatingImage. Совет: Ветвь Else этого виджета — это просто ProgressBar внутри Container с анимацией вращающегося цикла.
  • Виджет Image использует переменную logoImage для отображения логотипа.

3. Создайте и разверните Cloud Function

Чтобы создать и развернуть Cloud Function:

  1. Нажмите на Cloud Functions в Navigation Menu (слева на экране).
  2. Нажмите + Add. Это добавит шаблон newCloudFunction.
  3. Укажите Cloud Function Name.

Настройки шаблона

Справа вы можете настроить следующие параметры шаблона:

  1. Memory Allocation: Вы можете указать объем памяти, который должна иметь функция при выполнении, в зависимости от ее сложности и потребностей. Эта настройка важна, поскольку влияет на производительность функции и стоимость ее запуска. Больший объем памяти может улучшить производительность для интенсивных задач, но также повысит затраты.

  2. Timeout (s): Это максимальное время в секундах, в течение которого функция может выполняться, прежде чем будет автоматически завершена. Если ваша функция выполняется дольше, может потребоваться увеличить значение тайм-аута. Однако имейте в виду, что более длительные тайм-ауты могут привести к большим затратам, поскольку оплата зависит от времени выполнения.

  3. Require Authentication: Включите эту настройку, если хотите, чтобы пользователи проходили аутентификацию для выполнения этой cloud function.

  4. Cloud Function Region: Это определяет географическое расположение серверов, на которых размещаются и выполняются ваши функции. Идеально, если это совпадает с Default GCP resource location и регионом Cloud Function, указанным в расширенных настройках Firebase.

img_8.png

Настройка ввода и вывода

Ваша cloud function может требовать данные для обработки и возврата результата. Это можно сделать, настроив ввод и вывод.

  1. Чтобы получить вывод из Cloud Function, включите Return Value и выберите подходящий тип для вывода, например 'String' для текста. Для этого примера установите ImagePath, чтобы получить URL сгенерированного логотипа.

  2. Для ввода данных: Нажмите + Add parameters. Name параметра, выберите его Type, укажите одиночный или множественный элемент (опция Is List) и снимите флажок Nullable, если значение может быть null. Для этого примера добавьте параметр 'prompt' с Type = String.

  3. При использовании Custom Data Types, Cloud Function ожидает JSON, где каждое поле Data Type соответствует паре ключ-значение в JSON. Если Data Type — это список, функция ожидает список JSON. Например, для пользовательского типа данных 'Person' с полями 'Name' и 'Age' функция должна возвращать:

       //JSON:
{ "Name": "John", "Age": 30 }

//Example Cloud Function Code:
return {
"name": person.name,
"age": person.age
};

Для списка функция должна возвращать:

        //JSON
[ { "Name": "John", "Age": 30 }, { "Name": "Jane", "Age": 25 } ]

//Example Cloud Function Code:
return filteredpersons.map(filteredpersons => {
return {
"name": filteredpersons.name,
"age": filteredpersons.age
};
});

Развертывание

  1. Нажмите на иконку [</>], чтобы просмотреть шаблонный код; откроется всплывающее окно с обновленным кодом, затем нажмите </> Copy to Editor. Совет: Чтобы проверить, можно ли развернуть cloud function (до добавления вашего кода), сразу перейдите к шагам 8 и 9.

  2. В редакторе кода добавьте код cloud function. Совет: Вы можете скопировать шаблонный код в ChatGPT и попросить его написать нужный код на его основе.

  3. Нажмите Save Cloud Function.

  4. Нажмите Deploy.

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

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const https = require('https');

exports.logoMaker = functions.region('us-central1')
.runWith({
timeoutSeconds: 10,
memory: '512MB'
}).https.onCall((data, context) => {
return new Promise((resolve, reject) => {
const prompt = data.prompt;
if (!prompt) {
reject(new functions.https.HttpsError('invalid-argument', 'No prompt provided'));
return;
}

const postData = JSON.stringify({
model: "dall-e-3",
prompt: prompt,
n: 1,
size: "1024x1024"
});

const options = {
hostname: 'api.openai.com',
port: 443,
path: '/v1/images/generations',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer YOUR-APIKEY`,
'Content-Length': postData.length
}
};

const req = https.request(options, (res) => {
let responseBody = '';

res.on('data', (chunk) => {
responseBody += chunk;
});

res.on('end', () => {
try {
const responseJSON = JSON.parse(responseBody);
if (responseJSON.data && responseJSON.data.length > 0) {
// Retrieve the URL of the first image
const firstImageUrl = responseJSON.data[0].url;
resolve(firstImageUrl);
} else {
reject(new functions.https.HttpsError('not-found', 'No images found'));
}
} catch (error) {
reject(new functions.https.HttpsError('internal', 'Error processing response', error));
}
});
});

req.on('error', (error) => {
reject(new functions.https.HttpsError('internal', 'Error generating image', error));
});

req.write(postData);
req.end();
});
});
Важно

Всегда генерируйте и используйте обновленный шаблонный код или корректируйте свой код соответственно при любых изменениях в коде, настройках шаблона или параметрах ввода/вывода.

4. Опционально: Добавьте пакет

Ваша cloud function может требовать сторонние пакеты для работы. Вы можете включить любой npm-пакет (зависимость), перечислив его в файле package.json. Этот файл не только управляет зависимостями npm-пакетов для ваших функций, но и содержит метаданные проекта, настраивает скрипты для задач, таких как развертывание, и определяет совместимые версии Node.js.

Чтобы добавить зависимость, откройте файл package.json и укажите ваш пакет в разделе dependencies.

img_9.png

5. Запуск Cloud Function

Созданная Cloud Function будет доступна как действие при добавлении. Для этого примера при нажатии кнопки мы сначала установим generatingImage в True, а затем запустим Cloud Function Action.

6. Опционально: Используйте результат Cloud Function

Чтобы использовать результат Cloud Function, укажите Action Output Variable Name при добавлении действия, а затем вы сможете получить к нему доступ через Set from Variable menu > Action Outputs > [Action Output Variable Name].

Для этого примера мы используем результат (т. е. URL сгенерированного изображения логотипа) и устанавливаем его в переменную logoImage. Вот как это сделать:

Тестирование Cloud Functions в консоли Google Cloud

Консоль Google Cloud имеет встроенную функцию для запуска Cloud Function в целях тестирования. Это означает, что после развертывания Cloud Functions вы можете протестировать их без записи в Firestore (как из FlutterFlow, так и иным способом).

Вот как протестировать функцию sendUserPushNotificationsTrigger из FlutterFlow в консоли Google Cloud:

  1. Откройте браузер и перейдите по следующему URL: https://console.cloud.google.com/functions/details/us-central1/sendUserPushNotificationsTrigger?env=gen1&project=<projectID>&tab=testing
    Здесь:
    • Замените <projectID> на ваш проект GCP или Firebase.
    • Если вы хотите протестировать другую Cloud Function, обновите sendUserPushNotificationsTrigger с именем соответствующей cloud function.
  2. Вставьте следующий JSON в текстовую область Configure Triggering Event.
    • Если вы хотите протестировать другую Cloud Function, обновите sendUserPushNotificationsTrigger с именем соответствующей cloud function.
    {
    "value": {
    "name": "projects/<projectID>/databases/(default)/documents/sendUserPushNotificationsTrigger/<documentID>",
    "fields": {
    "scheduled_time": { "stringValue": "" },
    "initial_page_name": { "stringValue": "" },
    "notification_title": { "stringValue": "Your friends are missing you!" },
    "notification_text": { "stringValue": "Please come back to Nanochat" },
    "user_refs": { "stringValue": "users/VXu6EvFMl5M8KMXriYRvFEWTFHA2" }
    }
    }
    }
  3. В свойстве name:
    • Замените <projectID> на ваш проект GCP или Firebase.
    • Замените <documentID> на ID документа. Этот документ должен уже существовать в Firestore.
    • Если вы тестируете функцию, отличную от sendUserPushNotificationsTrigger, обновите ff_user_push_notifications с коллекцией, в которую записывается документ.
  4. Обновите значения в свойстве fields для сообщения, которое вы хотите отправить.
    Свойства fields в приведенном выше примере относятся к встроенной функции sendUserPushNotificationsTrigger из FlutterFlow. Если вы тестируете другую Cloud Function, вам потребуется обновить fields для кода этой функции.
  5. Нажмите кнопку TEST THE FUNCTION.

Cloud Function теперь запустится и соберет соответствующие записи из Google Cloud Logging.

Часто задаваемые вопросы

Почему развертывание cloud function не удается в новых проектах?

Эта проблема возникает потому, что новый проект Google Cloud Platform (GCP) не полностью настроен с необходимыми API и разрешениями. Следуйте шагам ниже, чтобы включить требуемые API и установить правильные разрешения.

  1. Откройте браузер и перейдите по следующему URL: https://console.cloud.google.com/functions/list?referrer=search&hl=en&project=<projectID> Замените <projectID> на ID вашего проекта GCP или Firebase.
  2. Нажмите кнопку Create Function. GCP предложит включить необходимые API: Cloud Build и Cloud Functions.
  3. После нажатия Next вам будет предложено включить Cloud Run Admin API. cloud-run-admin-api
  4. Теперь вам нужно предоставить учетной записи службы по умолчанию compute соответствующие разрешения. На следующей странице вы увидите опцию развернуть пример cloud function, такую как helloHttp. Разверните эту функцию. Вам будет предложено предоставить разрешения учетной записи службы compute по умолчанию. Сообщение будет выглядеть так: You need to grant the following roles to the build service account to deploy a function: roles/cloudbuild.builds.builder to <projectID>-compute@developer.gserviceaccount.com.
  5. Нажмите Grant, чтобы предоставить необходимые разрешения и развернуть пример cloud function. После развертывания вы можете удалить эту функцию, если пожелаете.

После предоставления необходимых разрешений вы сможете развертывать cloud functions из FlutterFlow без дальнейших проблем.

Я получаю ошибки развертывания Cloud Function

img_10.png

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

Почему я получаю ошибку CORS при выполнении Cloud Function?

Ошибка CORS возникает из-за отсутствия заголовка Access-Control-Allow-Origin в ответе, что не позволяет завершить запрос. Эта проблема может возникать с новыми Cloud Functions, независимо от того, развертываются ли они через FlutterFlow или нет.

Следуйте шагам ниже, чтобы исправить проблему:

  1. Откройте список Cloud Functions вашего проекта Google Cloud.
  2. Выберите функцию, вызывающую проблему.
  3. Перейдите на вкладку Permissions.
  4. Откройте вкладку VIEW BY ROLES.
  5. Убедитесь, что есть строка с Cloud Functions Invoker и principal, установленным в allUsers. Если ее нет, нажмите Grant Access, добавьте allUsers с ролью Cloud Functions Invoker.

add-cf-invoker-role