使用Angular集成OneSignal

8
我正在尝试将OneSignal集成到我的Angular 2应用程序中,以接收推送通知。首先,我使用普通的HTML创建了一个HelloWorld应用程序,并且它非常有效。所以我尝试将其包含到我的Angular应用程序中,但是用户没有被创建/注册,因此无法订阅接收任何通知。
代码摘录:
index.html
<html>

<head>
  <meta charset="utf-8">
  <title>My Angular App</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <head>
    <link rel="manifest" href="/manifest.json">
  <script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async></script>
  <script>
    var OneSignal = window.OneSignal || [];
    console.log("Init OneSignal");
    OneSignal.push(["init", {
      appId: "xxx-xxx-xxx-xxx-xxx",
      autoRegister: false,
      allowLocalhostAsSecureOrigin: true,
      notifyButton: {
        enable: true
      }
    }]);
    console.log('OneSignal Initialized');
    OneSignal.push(function () {
      console.log('Registered For Push');
      OneSignal.getUserId().then(function (userId) {
      console.log("User ID is", userId);
      });
    });
  </script>
  </head>
</head>

<body>
  <app-root>
    <div class="wrap">
      <div class="loading outer">
        <div class="loading inner"></div>
      </div>
    </div>
  </app-root>
</body>

</html>

userId 总是 null。

我已经检查了以下内容:

  • App ID 正确
  • 浏览器中通知权限设置为允许

问题:

  • 是否有一种方法可以在任何组件内部完成所有初始化工作,比如在 ngOnInit() 方法中?
  • 我想在用户单击组件内的按钮时注册推送,而不是使用铃铛图标。如何实现这一点?(我知道将 notifyButton 设置为 false 将不会显示通知铃铛)

P.S:使用 Angular CLI 在 Chrome 上测试(在 Firefox 或 Safari 上无效)

2个回答

19

很抱歉,我又出现了只浏览文档而不是认真阅读的情况。

于是我稍微修改了代码,最终这是起作用的代码。

index.html

<html>

<head>
  <meta charset="utf-8">
  <title>My Angular App</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <head>
    <link rel="manifest" href="/manifest.json">
  <script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async='async'></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
  </head>
</head>

<body>
  <app-root>
    <div class="wrap">
      <div class="loading outer">
        <div class="loading inner"></div>
      </div>
    </div>
  </app-root>
</body>

</html>

app.component.ts

:这是一个与Angular框架相关的TypeScript文件,其中包含组件代码。
export class AppComponent implements OnInit {
    .
    .
    .
    .
    ngOnInit() {
    var OneSignal = window['OneSignal'] || [];
    console.log("Init OneSignal");
    OneSignal.push(["init", {
      appId: "xxx-xxx-xxx-xxx",
      autoRegister: false,
      allowLocalhostAsSecureOrigin: true,
      notifyButton: {
        enable: false
      }
    }]);
    console.log('OneSignal Initialized');
    OneSignal.push(function () {
      console.log('Register For Push');
      OneSignal.push(["registerForPushNotifications"])
    });
    OneSignal.push(function () {
      // Occurs when the user's subscription changes to a new value.
      OneSignal.on('subscriptionChange', function (isSubscribed) {
        console.log("The user's subscription state is now:", isSubscribed);
        OneSignal.getUserId().then(function (userId) {
          console.log("User ID is", userId);
        });
      });
    });
    }
    .
    .
    .
}

需要注意的几点:

  • 监听subscriptionChange事件,然后获取用户ID。
  • 当用户手动在浏览器中禁用通知时,也会触发subscriptionChange事件。
  • autoRegister: false,不会提示“允许”/“拒绝”的选项。因此我们需要调用registerForPushNotifications方法。可以使用此方法在单击按钮或其他操作时提示用户开启推送通知。

编辑2018年

我制作了一个实用类,可在我所有的angular项目中使用它来减少onesignal的模板代码。

https://gist.github.com/PsyGik/54a5e6cf5e92ba535272c38c2be773f1


1
也适用于带有 angular-cli 的 Angular 5。非常感谢,你救了我的一天! :) - Maxime Lafarie
2
你把SDK放在哪里?只有/assets/是公开的!你如何解决这个问题?GET http://localhost:4200/OneSignalSDKWorker.js?appId=xxxx 404 (未找到) - Suisse
@Suisse,对于我的项目,我已将文件保存在src文件夹中。然后在.angular-cli.json文件中只需提及文件的位置即可。仅/assets/是公开的并不正确。您可以将任何文件/文件夹路径添加到cli.json文件中的资产部分。 - PsyGik
在我的情况下,OneSignal服务工作者与Angular服务工作者不兼容。OneSignal团队表示,我必须将Angular服务工作者放置在不同的文件夹中,然后需要导入它。这怎么可能呢? - Deepak swain
@Deepakswain,如果您能分享相关代码,我可能能够帮助您解决问题。更好的方法是,创建另一个问题并提供所有细节。 - PsyGik
@PsyGik 谢谢你的提示。为什么我找不到那个信息呢?谢谢。 - Suisse

3
最简单的解决方法是将One Signal提供的脚本放入您的index.html中。
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
    <meta
      content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
      name="viewport"
    />

    ...
    ...

    <link rel="manifest" href="/manifest.json" />
    <script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async=""></script>
    <script>
      var OneSignal = window.OneSignal || [];
      OneSignal.push(function() {
        OneSignal.init({
          appId: 'xxx-xxxx-xxxxx',
        });
      });
    </script>

    ...

将以下内容添加到 angular.json 文件中。

    ...
    "architect": {
        "build": {
          "builder": "ngx-build-plus:build",
          "options": {
            "outputPath": "dist/browser",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/favicon.png",
              "src/manifest.json", <-- this 
              "src/OneSignalSDKUpdaterWorker.js", <-- this 
              "src/OneSignalSDKWorker.js", <-- and finally this one
              "src/assets"
            ],
            "styles": [ 
              "src/styles.scss"
            ],
            "stylePreprocessorOptions": {
              "includePaths": ["src/assets/sass"]
            },
            "scripts": []
          },
          ...

将清单和2个*.js文件放入/src/*即可。

就这样,您需要将其发布到您的服务器而不是本地主机:4200。 我使用这种方法使它正常工作。希望能有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接