#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:
После тщательного расследования я смог подтвердить следующее:
- «Flutter SDK» предназначен только для мобильных приложений, он не работает в веб-приложениях
- Для веб-приложений мы должны использовать «Веб-SDK», т. е. использовать Java-скрипт, а не Flutter
- Для мобильных и веб-можем ли мы использовать 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