Есть список городов - далее messages (все сообщения) и далее список пользователей этого города users
{ "Ижевск" : {
"messages" : {
"-L-HZZkAurZ0l5VTUOjD" : {
"MediaType" : "TEXT",
"date" : "18:54",
"senderId" : "687",
"senderName" : "Александр Александрович",
"text" : "Ижевск привет",
"token" : "dWg66sXaXHw:APA91bHXXAhzW8a7NThGBrWTjlIiukx1oqbVV6XAT"
}
},
"users" : {
"Александр Александрович" : {
"isNotificationsEnabled" : true,
"platform" : "android",
"token" : "dWg66sXaXHw:APA91bHXXAhzW8a7NThGBrWTjlIiukx1oqbVV6XAT"
},
"Петя Александрович" : {
"isNotificationsEnabled" : true,
"platform" : "ios",
"token" : "dWg66sXaXHw:APA91bHXXAhzW8a7NThGBrWTjlIiukx1oqbVV6XAT"
}
}
}
}
Мы с помощью метода functions.database.ref('/{city}/messages/{msgID}').onWrite … отслеживаем когда пришло новое сообщение
И далее наша задача отправить пуш уведомление с помощью метода admin.messaging().sendToDevice(tokens, payload)
Но для этого мы должны собрать все токены устройств пользователей, и здесь у меня проблема.
Не получается пройтись в цикле по базе и собрать все токены. Что не так с функцией?
Мой код на Node.JS
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var city = "";
exports.sendFollowerNotification = functions.database.ref('/{city}/messages/{msgID}').onWrite(event => {
var eventSnapshot = event.data;
//текст сообщения
var textMsg = eventSnapshot.child("text").val();
//имя отправителя
var senderName = eventSnapshot.child("senderName").val();
//токен отправителя, чтобы потом его исключить
var tokenOfSender = eventSnapshot.child("token").val();
//получаем город в котором было отправлено сообщение
var cityTemp = (event.data.ref.toString().split('/'))[3];
city = cityTemp; //записываем в глобальную переменную
//дальше начинаются проблемы
return loadUsers().then(users => {
let tokens = [];
for (let user of users) {
tokens.push(user.token);
}
console.log('TOKENSARRAY = ' + tokens); // = null
let payload = {
notification: {
title: 'Сообщние от ' + senderName + ':',
body: textMsg,
sound: 'default',
badge: '1'
}
};
return admin.messaging().sendToDevice(tokens, payload);
});
});
function loadUsers() {
let dbRef = admin.database().ref('/' + city + '/users');
let defer = new Promise((resolve, reject) => {
dbRef.once('value', (snap) => {
let data = snap.val(); // = null, и дальше логично, что ничего не выйдет по задумке
let users = [];
for (var property in data) {
users.push(data[token]);
}
resolve(users);
}, (err) => {
reject(err);
});
});
return defer;
}
Вот рабочая функция, стоит на чате проекта firebase-info.com спецом перевел на русский для вас.
// Импортируем Firebase SDK для облачных функций
const functions = require('firebase-functions');
// Импортируем и инициализируем Firebase Admin SDK.
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
// Добавляем сообщение которое приветствует нового пользователя в чате
exports.addWelcomeMessages = functions.auth.user().onCreate(event = > {
const user = event.data;
console.log('Новый пользователь зарегистрировался в чате');
const fullName = user.displayName || 'Аноним';
// Сохраняет сообщение в базу данных -> веб приложение слышет это и отображает сообщение
return admin.database().ref('messages').push({
name: 'Бот firebase-info.com',
photoUrl: '/images/k-logo.png',
text: `${fullName} зарегистрировался в чате! Приветствуем`
});
})
;
// Отбравляем пуш уведомление всем пользователя о новом сообщении в чате
exports.sendNotifications = functions.database.ref('/messages/{messageId}').onWrite(event = > {
const snapshot = event.data;
// Отправляем пуш уведомление только в случае если новое сообщение было создано
if (snapshot.previous.val()) {
return;
}
// Детали пуш уведомления
const text = snapshot.val().text;
const payload = {
notification: {
title: `${snapshot.val().name} опубликовал ${text ? 'сообщение' : 'изображение'}`,
body: text ? (text.length <= 100 ? text : text.substring(0, 97) + '...') : '',
icon: snapshot.val().photoUrl || '/images/profile_placeholder.png',
click_action: `https://${functions.config().firebase.authDomain}`
}
};
// Берем список fcm токенов девайсов.
return admin.database().ref('fcmTokens').once('value').then(allTokens = > {
if(allTokens.val()
)
{
// Листаем все токены
const tokens = Object.keys(allTokens.val());
// Отправляем сообщение ко всем токенам
return admin.messaging().sendToDevice(tokens, payload).then(response = > {
// Для каждого сообщения проверь была ли ошибка
const tokensToRemove = [];
response.results.forEach((result, index) = > {
const error = result.error;
if (error) {
console.error('Ошибка отправления пуш уведомления', tokens[index], error);
// Удаляем токены которые более не зарегистрированы
if (error.code === 'messaging/invalid-registration-token' ||
error.code === 'messaging/registration-token-not-registered') {
tokensToRemove.push(allTokens.ref.child(tokens[index]).remove());
}
}
})
;
return Promise.all(tokensToRemove);
})
;
}
})
;
})
;
У меня открывается фотография в модальном окне, она открывается как canvasПроблема в том что Рамочка для вырезания может выходить за пределы...
Добрый день, помогите найти ближайший элемент на странице с помощью JavaScriptСейчас у меня находит ближайший элемент только по X