Как передать аргументы из функций Dart в Cloud, написанные на Typescript, и это также дает мне код ошибки UNAUTHENTICATED - PullRequest
1 голос
/ 24 апреля 2020

Функция Dart (передача token в sendToDevice):

Future<void> _sendNotification() async {
  CloudFunctions functions = CloudFunctions.instance;
  HttpsCallable callable = functions.getHttpsCallable(functionName: "sendToDevice");

  callable.call({
    'token': await FirebaseMessaging().getToken(),
  });
}

index.ts файл, в котором я определил sendToDevice метод.

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();

const fcm = admin.messaging();

export const sendToDevice = functions.firestore
  .document('users/uid')
  .onCreate(async snapshot => {

    const payload: admin.messaging.MessagingPayload = {
      notification: {
        title: 'Dummy title',
        body: `Dummy body`,
        click_action: 'FLUTTER_NOTIFICATION_CLICK'
      }
    };

    return fcm.sendToDevice(tokens, payload); // how to get tokens here passed from above function?
  }
);

Вопросы:

  1. Как получить токены, переданные из функции Dart _sendNotification в функцию Typescript sendToDevice.

  2. Когда я непосредственно передавал токены из файла index.ts, я получал следующее исключение:

[ОШИБКА: флаттер / lib / ui / ui_dart_state. cc (157)] Необработанное исключение: PlatformException (functionsError, облачная функция не выполнена, исключение., {code: UNAUTHENTICATED, подробности: null, сообщение: UNAUTHENTICATED})

Может кто-нибудь объяснить, если я должен здесь что-то подтвердить? Команда firebase login показывает, что я уже вошел в систему. Я новичок в Typescript, поэтому, пожалуйста, ответьте на эти глупые вопросы.

Ответы [ 5 ]

1 голос
/ 04 мая 2020

Ваша сторона флаттера в коде кажется правильной, а то, что неправильно, в облачной функции.

Функция sendToDevice не является вызываемой функцией. Это Cloud Firestore Trigger , он предназначен для автоматического вызова только при создании документа, соответствующего users/{uid}.

Вместо этого вы захотите создать Callable Функция , см. Ниже

export const sendToDevice = functions.https
  .onCall(async (data) => {
    const { token } = data; // Data is what you'd send from callable.call

    const payload: admin.messaging.MessagingPayload = {
      notification: {
        title: 'Dummy title',
        body: `Dummy body`,
        click_action: 'FLUTTER_NOTIFICATION_CLICK'
      }
    };

    return fcm.sendToDevice(token, payload);
  }
);
1 голос
/ 24 апреля 2020

Здесь нужно упомянуть несколько вещей:

1st Функция, используемая в getHttpsCallable, должна запускаться триггером https (ссылка здесь ). Здесь у нас есть функция, инициируемая созданием документа firestore, поэтому она не будет работать.

2nd У вас нет параметра вашей функции, но вы вызываете его с параметрами. Если вам нужен пример вызова облачной функции с параметром, вы можете найти ее на pud.dev

3-й. Сейчас у меня нет возможности поиграть с ней, но я думаю, что если вы Реализовав функцию HTTPS с параметром token, вы сможете передать этот параметр.

Надеюсь, это поможет!

ОБНОВЛЕНИЕ:

Согласно do c Функция запуска https должна быть создана с помощью functions.https. В do c есть хороший пример. Чтобы функция сработала таким образом, вы можете добавить тело запроса, когда сможете передавать необходимые данные.

0 голосов
/ 06 мая 2020

Сделать функцию доступной c

Проблема связана с учетными данными. Вы можете изменить политику безопасности CF и sheck, если проблема устранена. Смотрите, как управлять разрешениями на CF здесь

0 голосов
/ 06 мая 2020

Этот ответ, возможно, не решит вашу проблему, но даст вам несколько вещей, которые вы можете попробовать, и вы научитесь на этом пути. К сожалению, я не смог заставить вызываемый https работать с эмулятором. Я, вероятно, скоро сообщу о проблеме на github. Приложение флаттера продолжает получать разные типы нешифруемых ошибок в зависимости от локального URL-адреса, который я пробую.


Хорошо, что вы исправили одну из проблем: вы использовали триггер документа (onCreate) вместо вызываемого HTTPS. Но теперь вы используете протокол HTTPS, и приложения Flutter должны напрямую взаимодействовать с вашими функциями. В будущем вы могли бы запускать эмулятор функций локально и много console.log 'понять, запускается ли он на самом деле.

У меня есть несколько вопросов / вещей, которые вы можете попробовать:

  • Ваш пользователь вошел в приложение флаттера? FirebaseAuth.instance.currentUser() скажет вам.
  • Эта проблема возникает как на iOS, так и на android?
  • Добавьте несколько журналов в вашу функцию машинописи и повторите развертывание. Читайте последние журналы через StackDriver или в терминале, firebase functions:log --only sendToDevice. (sendToDevice - это название вашей вызываемой функции)
  • Развертываете ли вы в облаке и тестируете с последним развертыванием ваших функций? На самом деле вы можете протестировать с локальным эмулятором . На Android URL-адрес 10.0.2.2:5001, как показано выше. Вам также нужно запустить adb reverse tcp:5001 tcp:5001 в терминале. Если вы находитесь в облаке, то firebase login не имеет значения, Я думаю, ваши функции уже должны иметь учетные данные.

Чтобы вызвать эмулятор, вызываемый по протоколу https:

HttpsCallable callable = CloudFunctions.instance
    .useFunctionsEmulator(origin: "http://10.0.2.2:5001")
    .getHttpsCallable(functionName: "sendToDevice");

и iOS вам нужно следовать решению здесь .

Одна ошибка, которую я обнаружил. Вы должны, по крайней мере, сделать return await fcm.sendToDevice() там, где вы ожидаете разрешения обещания, потому что в противном случае среда выполнения облачной функции прекратит работу вашей функции, прежде чем она разрешится. В качестве альтернативы, для отладки, вместо возврата sendToDevice в облачную функцию, вы могли бы сохранить ее в переменную и console.log. Вы увидите его обещание (или будущее в терминологии дротика), которое на самом деле не решено.

 const messagingDevicesResponse: admin.messaging.MessagingDevicesResponse = await fcm.sendToDevice(
    token,
    payload
  );
  console.log({ messagingDevicesResponse });
  return;
0 голосов
/ 04 мая 2020

Вы создали триггер базы данных, вам нужно создать вызываемую функцию, как показано ниже

exports.sendToDevice = functions.https.onCall(async (data, context) => {
    const payload: admin.messaging.MessagingPayload = {
        notification: {
          title: 'Dummy title',
          body: `Dummy body`,
          click_action: 'FLUTTER_NOTIFICATION_CLICK'
        }
      };

      return await fcm.sendToDevice(data.token, payload);
  });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...