Функции Firebase просто вымирают без объяснений или ошибок - PullRequest
0 голосов
/ 16 мая 2019

Я пытаюсь реализовать приложение для обмена сообщениями, используя Firebase Firestore и Firebase Cloud Functions.

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

Итак, я создал функцию для отправки сообщений, которая создает документы от имени пользователей, когда пользователи вызывают функцию из приложения (т.е. нажимают кнопку отправки).

Функция сработала, и я смог отслеживать процессы через журналы.К сожалению, функции начали исчезать без ошибок, консоль сообщала, что функции выполняются успешно, и на выполнение обычно уходило менее секунды.

Я подозреваю, что это как-то связано с обещаниями, которые, вероятно, продолжают выполняться, но это тот же код, который работал, но не работал сегодня.

Если я попробую еще несколько раз,функции, кажется, снова работают.Нужно ли держать функции "в тепле"?Облачные функции недостаточно надежны для решения подобных задач?Когда я говорю своему пользователю, что сообщение отправлено, я должен иметь возможность подтвердить, что оно отправлено, и сообщить о нем пользователям, если оно не удалось.

Трудно отладить проблему, потому что не выдается никаких ошибок (даже не информационное сообщение, это как будто не произошло), он просто говорит, что функция успешно завершила выполнение и ничего не произошло.

Я что-то здесь упустил?Спасибо.

exports.sendMessage = functions.https.onCall((data, context) => {
  if (context.auth.uid == undefined) {
    console.warn("SEND MESSAGE: USER NOT SIGNED IN");
    return;
  }

  console.log("Sending message:", data)
  const matchId = data["matchId"];
  const message = data["message"]
  const uid = context.auth.uid

  admin.firestore().collection(MatchingUsers).doc(matchId).collection(UserMessages).add({
    type: "text",
    from: uid,
    message: message,
    timestamp: admin.firestore.Timestamp.now()
  }).then(result => {
    console.log("Message sent")
  }).catch(err => {
    console.log("Error sending mesage:", err)
  })
})

1 Ответ

2 голосов
/ 16 мая 2019

Как описано в документации к функциям вызываемого облака HTTP :

Чтобы вернуть данные после асинхронной операции, верните обещание.

Затем следует пример:

const sanitizedMessage = sanitizer.sanitizeText(text); // Sanitize the message.
return admin.database().ref('/messages').push({
  text: sanitizedMessage,
  author: { uid, name, picture, email },
}).then(() => {
  console.log('New Message written');
  // Returning the sanitized message to the client.
  return { text: sanitizedMessage };
})

Так что вам нужно адаптировать ваш код следующим образом:

exports.sendMessage = functions.https.onCall((data, context) => {
  if (context.auth.uid == undefined) {
    console.warn("SEND MESSAGE: USER NOT SIGNED IN");
    //Here send back an error as explained here: https://firebase.google.com/docs/functions/callable#handle_errors
  }

  console.log("Sending message:", data)
  const matchId = data["matchId"];
  const message = data["message"]
  const uid = context.auth.uid

  //Note the return on next line
  return admin.firestore().collection(MatchingUsers).doc(matchId).collection(UserMessages).add({
    type: "text",
    from: uid,
    message: message,
    timestamp: admin.firestore.Timestamp.now()
  }).then(result => {
    console.log("Message sent");
    return { text: "Message sent" };
  }).catch(err => {
    console.log("Error sending mesage:", err);
    //Here, again, send back an error as explained here: https://firebase.google.com/docs/functions/callable#handle_errors
  })
})

Если вы не хотите возвращать значение клиенту, вы можете сделать следующее, возвращая null, когда Обещание, возвращаемое асинхронным методом add(), разрешается. (Не проверено, но должно работать).

exports.sendMessage = functions.https.onCall((data, context) => {
  if (context.auth.uid == undefined) {
    console.warn("SEND MESSAGE: USER NOT SIGNED IN");
    return null;
  }

  console.log("Sending message:", data)
  const matchId = data["matchId"];
  const message = data["message"]
  const uid = context.auth.uid

  //Note the return on next line
  return admin.firestore().collection(MatchingUsers).doc(matchId).collection(UserMessages).add({
    type: "text",
    from: uid,
    message: message,
    timestamp: admin.firestore.Timestamp.now()
  }).then(result => {
    console.log("Message sent");   //Actually, if you don't need this console.log() you can remove this entire then() block, returning the promise from add() is enough
    return null;
  }).catch(err => {
    console.log("Error sending mesage:", err);
    return null;
  })
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...