Можно ли использовать OneSignal с Flutter-Web?

#flutter-web #onesignal #flutter-plugin

Вопрос:

Вызов любой из функций OneSignal отлично работает на Android, но в Интернете он вызывает следующее исключение. Обратите внимание, что часть подписки работает, у меня был установлен идентификатор приложения в index.html, Я загрузил файлы js сотрудника службы и получил первое приветственное сообщение.

Но мне нужно иметь возможность получить «Идентификатор игрока» и сохранить его, а также иметь возможность отправлять уведомления из Интернета.

Пример вызовов функций OneSignal:

   await OneSignal.shared.setAppId(kOneSignalAppId);
  OSDeviceState? deviceState = await OneSignal.shared.getDeviceState();
  OneSignal.shared.postNotification(notification);
 

Исключение:

 Error: MissingPluginException(No implementation found for method OneSignal#log on channel OneSignal)
at Object.throw_ [as throw] (http://localhost:49430/dart_sdk.js:5079:11)
at MethodChannel._invokeMethod (http://localhost:49430/packages/flutter/src/services/restoration.dart.lib.js:1526:21)
at _invokeMethod.next (<anonymous>)
at http://localhost:49430/dart_sdk.js:38749:33
at _RootZone.runUnary (http://localhost:49430/dart_sdk.js:38620:59)
at _FutureListener.thenAwait.handleValue (http://localhost:49430/dart_sdk.js:33820:29)
at handleValueCallback (http://localhost:49430/dart_sdk.js:34372:49)
at Function._propagateToListeners (http://localhost:49430/dart_sdk.js:34410:17)
at _Future.new.[_completeWithValue] (http://localhost:49430/dart_sdk.js:34258:23)
at async._AsyncCallbackEntry.new.callback (http://localhost:49430/dart_sdk.js:34279:35)
at Object._microtaskLoop (http://localhost:49430/dart_sdk.js:38887:13)
at _startMicrotaskLoop (http://localhost:49430/dart_sdk.js:38893:13)
at http://localhost:49430/dart_sdk.js:34626:9

Error: MissingPluginException(No implementation found for method OneSignal#setAppId on channel OneSignal)
at Object.throw_ [as throw] (http://localhost:49430/dart_sdk.js:5079:11)
at MethodChannel._invokeMethod (http://localhost:49430/packages/flutter/src/services/restoration.dart.lib.js:1526:21)
at _invokeMethod.next (<anonymous>)
at http://localhost:49430/dart_sdk.js:38749:33
at _RootZone.runUnary (http://localhost:49430/dart_sdk.js:38620:59)
at _FutureListener.thenAwait.handleValue (http://localhost:49430/dart_sdk.js:33820:29)
at handleValueCallback (http://localhost:49430/dart_sdk.js:34372:49)
at Function._propagateToListeners (http://localhost:49430/dart_sdk.js:34410:17)
at _Future.new.[_completeWithValue] (http://localhost:49430/dart_sdk.js:34258:23)
at async._AsyncCallbackEntry.new.callback (http://localhost:49430/dart_sdk.js:34279:35)
at Object._microtaskLoop (http://localhost:49430/dart_sdk.js:38887:13)
at _startMicrotaskLoop (http://localhost:49430/dart_sdk.js:38893:13)
at http://localhost:49430/dart_sdk.js:34626:9
 

Нужен ли для этого веб-плагин?
Существует ли он или я должен его создать?
Если да, то не могли бы вы, пожалуйста, сказать мне, как это сделать?

Ответ №1:

После тщательного расследования я смог подтвердить следующее:

  1. «Flutter SDK» предназначен только для мобильных приложений, он не работает в веб-приложениях
  2. Для веб-приложений мы должны использовать «Веб-SDK», т. е. использовать Java-скрипт, а не Flutter
  3. Для мобильных и веб-можем ли мы использовать API-интерфейс REST, но в большинстве случаев потребуется приложение-идентификатор, имя пользователя и ключ API, поэтому для initilaization и получения имени мы еще нужны «флаттер СДК» для мобильных приложений или «веб-СДК» на веб-это, как мне удалось заставить его работать на обеих мобильных и веб-приложение с тем же кодом: для веб-части
  • Инициализация с помощью веб-пакета SDK
  • Получение идентификатора игрока с помощью веб-пакета SDK
  • Сохранение идентификатора игрока в скрытом элементе с помощью javascipt
  • Извлеките идентификатор игрока из кода Flutter с помощью пакета «universal_html» .
  • Настройка внешнего идентификатора с помощью REST API
  • Отправка уведомлений через REST API

Для мобильной части

  • Инициализация с помощью Flutter SDK
  • Получение идентификатора игрока с помощью Flutter SDK
  • Настройка внешнего идентификатора с помощью Flutter SDK
  • Отправка уведомления через REST API (так как Flutter SDK не может отправлять на внешний идентификатор)

index.html

 <head>
  ...
  <script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async=""></script>
  <script>
    var OneSignal = window.OneSignal || [];
    var initConfig = {
      appId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      persistNotification: true,
      notifyButton: {
          enable: true
      },
    };
    OneSignal.push(function () {
      OneSignal.init(initConfig);
    });
  </script>
</head>
<body>
  <input type="hidden" id="osUserID" value="ERR" />
  ...
  <script>
    var eUserID = document.getElementById('osUserID');
    function getUserId() {
      OneSignal.getUserId(function(osUserID) {
        if (eUserID amp;amp; osUserID) {
          eUserID.value = osUserID;
          }
      });
    }
    OneSignal.push(function () {
      OneSignal.isPushNotificationsEnabled(function(isEnabled) {
        if (isEnabled) getUserId();
      });
      OneSignal.on('subscriptionChange', function (isSubscribed) {
        if (isSubscribed) getUserId();
      });
    });
  </script>
</body>
 

Изнутри Трепещут

   import 'package:flutter/foundation.dart';
  import "package:universal_html/html.dart";
  import 'package:onesignal_flutter/onesignal_flutter.dart';
  import 'onesignal_api.dart';
  ...
  Future<String> getPlayerId(String exteralId) async {
    String _osUserID;
    if (kIsWeb){
      InputElement? element = querySelector("#osUserID") as InputElement?;
      osUserID = element?.value??"Not Subscribed";
      await _oneSignalAPI.setExternalId(osUserID, exteralId);
    }
    else {
      await OneSignal.shared.setAppId(kOneSignalAppId);
      OSDeviceState? deviceState = await OneSignal.shared.getDeviceState();
      osUserID = deviceState?.userId??"Not Subscribed";
      await OneSignal.shared.setExternalUserId(exteralId);
    }
    return osUserID;
  }
  Future<void> sendMessage(String exteralId, String message) async {
    _oneSignalAPI.sendNotification(exteralId, message);
  }
 

Ответ №2:

У OneSignal есть SDK для веб-push, flutter web-это веб-сайт (веб-приложение) в конце, поэтому вам следует настроить OneSignal для Интернета и попробовать его.

Один Сигнал

Вы можете сделать это, чтобы получить идентификатор игрока с помощью JavaScript:

 OneSignal.push(function() {
/* These examples are all valid 
*/

OneSignal.getUserId(function(userId) {
console.log("OneSignal User ID:", userId);
// (Output) OneSignal User ID: 270a35cd-4dda-4b3f-b04e-41d7463a2316    
  });
});

//Another example:

OneSignal.push(function() {               

OneSignal.getUserId().then(function(userId) {
console.log("OneSignal User ID:", userId);
// (Output) OneSignal User ID: 270a35cd-4dda-4b3f-b04e-41d7463a2316    
  });
});
 

Затем вы можете передать его в код flutter по URL-адресу.

Комментарии:

1. Я уже сделал это, именно так я «получаю» уведомления, и я также могу видеть идентификаторы игроков подписанного пользователя на панели управления OneSignal, это в основном добавление конфигурации в index.html <заголовок> и загрузка файлов sdk (файлы service worker .js). Но мой вопрос касается доступа к OneSignal изнутри кода Flutter, как я делал в версии для Android.

2. Не могли бы вы уточнить, как передать идентификатор пользователя в flutter, как вы упомянули в своем обновленном ответе?

3. После того, как вы получили идентификатор пользователя, отправьте ему конкретную страницу. Вот так www.yourdomain.com/register уведомление/Идентификатор пользователя=xxxxxxxxxxxx

4. Извините, но я все еще не понимаю, как прочитать эту информацию в коде flutter.

5. Вы должны создать страницу, которая считывает переменные URL (это может быть главная страница). Затем код JavaScript в html перенаправит пользователя на эту страницу и добавит идентификатор пользователя в URL-адрес, после чего ваш код flutter сможет его прочитать. Например: example.com/main? Идентификатор пользователя=123456