Задача: когда пользователь заходит в мобильное приложение, нужно сохранить FCM токен устройства в пользовательское поле "Токены устройств". Поле является множественной строкой - так как у пользователя может быть не одно устройство.
Запись в пользовательское поле через API
Множественное поле имеет код UF_PUSH_DEVICE_TOKENS. Для записи в это поле можно воспользоваться API 1С-Битрикс:
$user = new CUser;
$userId = $USER->GetID();
$fields = ["UF_PUSH_DEVICE_TOKENS" => 'Значение'];
$user->Update($userId, $fields)
Но, нам нужно не просто добавить запись в поле но и сохранить предыдущие значения. Для реализации, лучше всего завернуть весь в функционал в компонент.
Пример компонента с получением токена устройства. Файл component.php:
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
use Bitrix\Main\Loader;
use Bitrix\Main\UserTable;
Loader::includeModule("main");
global $USER;
if (
$_SERVER['REQUEST_METHOD'] === 'POST' &&
isset($_POST['token']) &&
$USER->IsAuthorized()
) {
$userId = $USER->GetID();
$newToken = htmlspecialchars(trim($_POST['token']));
// Получаем текущие значения поля UF_PUSH_DEVICE_TOKENS
$arResult = UserTable::getList([
'filter' => ['ID' => $userId],
'select' => ['UF_PUSH_DEVICE_TOKENS']
])->fetch();
$currentTokens = $arResult['UF_PUSH_DEVICE_TOKENS'];
if (!is_array($currentTokens)) {
$currentTokens = [];
}
// Проверяем, есть ли такой токен в массиве
if (!in_array($newToken, $currentTokens)) {
$currentTokens[] = $newToken;
// Подготавливаем поля для обновления
$fields = [
'UF_PUSH_DEVICE_TOKENS' => $currentTokens
];
$user = new CUser;
if ($user->Update($userId, $fields)) {
// echo "Поле успешно обновлено.";
} else {
// echo "Ошибка при обновлении поля: " . $user->LAST_ERROR;
}
} else {
// echo "Токен уже существует.";
}
die(); // Завершаем выполнение скрипта после обработки AJAX-запроса
}
$this->includeComponentTemplate();
- Здесь мы проверяем, авторизован ли пользователь, получаем все значения поля UF_PUSH_DEVICE_TOKENS и наполняем ими массив $currentTokens.
- Если полученный токен отсутствует в этом массиве, то добавляем его в массив $currentTokens и обновляем поле UF_PUSH_DEVICE_TOKENS, перезаписывая все его значения с добавлением нового токена.
В коде выше мы получаем текущий токен устройства с помощью AJAX. Для получения и отправки токена используем FirebasePlugin.
Данная заметка является дополнением к Настройка push уведомлений через Firebase. Но подойдет как пример и для других задач в которых требуется обновлять пользовательские поля через API
Размещаем этот код в template.php. Здесь мы получаем токен и отправляем его AJAX-ом на эту же страницу (по факту на наш обработчик в component.php):
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
setTimeout(() => { // Не большая задержка нужна для iOS
window.FirebasePlugin.getToken(function (token) {
// alert(token); // Сохраняем этот токен в базе данных сайта
// Отправляем токен на сервер
$.ajax({
url: '',
type: 'POST',
data: {
token: token
},
success: function (response) {
//console.log('Token saved successfully: ' + response);
},
error: function (xhr, status, error) {
//console.error('Error saving token: ' + error);
}
});
}, function (error) {
//console.log(error);
});
}, 100);
}
Ключевые моменты:
- Проверка авторизации пользователя.
- Получение текущих значений пользовательского поля.
- Добавление нового токена в список, если его там нет.
- Обновление пользовательского поля с новым списком токенов.
Этот подход обеспечивает сохранение всех токенов устройств пользователя и предотвращает дублирование токенов в базе данных.