推送(Push)越来越成为 App 运营的必备手段,成为 App 开发中必备的功能。
但是,推送给谁?是个问题。
本文以极光推送作为范例,重点说说推送人群(Audience)选择的技术问题。其他推送云服务也或多或少有些类似。
极光推送(JPush)在推送人群的选择上,支持如下几种方式:
广播(所有人)
注册 ID(RegistrationID)
别名(alias)
标签(tag ,分组)
用户分群(Segment)
推送人群可选类别
以下先分别解析以上几个推送人群类型,及其具体用法。之后再谈谈他们的适用场景,以及如何区别使用。
注册 ID(RegistrationID)
RegistrationID 就是这台设备(以及当前这个 App),被推送服务器分配的唯一 ID 。不同的设备、不同的 App 这个 ID 肯定不同的。
SDK 在第一次启动时会去服务器端进行注册并识别,服务器端会分配一个 RegistrationID 。 SDK 会把这个 ID 通过广播(或通知)的方式发给 App 。 SDK 也提供了获取 RegistrationID 的接口。
如果一个 App 在这台设备上之前安装过,然后被卸载掉。重新安装时,其获取到的 RegistrationID 有一定的可能性不变。这取决于平台以及条件。
Android 上 JPush 会综合利用多个条件来判断设备是否相同,从而 RegistrationID 不变的可能性很大。
iOS 老版本上,因为 device token 重新安装 App 时也不会变,从而 RegistrationID 也一般不会变。
iOS8 以后重新安装 App 会导致 device token 变更, iOS 上如果不启用 IDFA 则没有其他可用于识别设备的手段,从而 RegistrationID 一般会变化。或者说,服务器端无法识别重新安装。所以如果你的业务有需要,建议启用 IDFA 。
使用 RegistrationID 推送的关键于, App 开发者需要在开发 App 时,获取到这个 RegistrationID ,保存到 App 业务服务器上去,并且与自己的用户标识对应起来。
建议 App 开发者尽可能做这个保存动作。因为这是最精确地定位到设备的。
别名(alias)
别名可以理解为基于 RegistrationID ,设置一个更容易理解的『别名』,比如直接设置为当前登录用户的 username 。
一个设备(在一个 App 里)只能设置一个别名。
别名的本质是,把 App 用户体系里的用户 ID 与 RegistrationID 的对应关系,保存到推送服务器上,而不是保存到 App 业务服务器上去。(使用 RegistrationID 就是把对应关系保存到 App 业务服务器上去。)
设置了别名后,推送时服务器端指定别名即可。推送服务器端来把别名转化到 RegistrationID 找到设备。
别名可以在客户端设置,服务器端也提供了 REST API 进行设置。但是,在一个 App 的生命周期中,强烈建议不要既在客户端又在服务器端进行设置,否则会导致混乱。
标签(tag)
又或者称为分组推送。对于大量的设置了同一个标签的终端,可以一次推送到到达。一个应用里一个标签绑定到的设备数没有限制。
一个设备(在一个 App 里)可以设置多个标签。
标签与别名类似,其对应关系也是保存在推送服务器侧的。
与别名类似,标签也是可以在客户端设置,服务器端也开放了 REST API 进行设置。同样,也是强烈建议,不要既在客户端设置标签,又在服务器端设置标签,以免造成混乱。
用户分群(Segment)
这是相对高级的使用方式了,开发者可以根据一些已知的条件,任意组合,创建一个 SegmentID 。然后基于这个 SegmentID 进行推送。
上面说到的可以用于用户分群的条件有: tags , App 版本, SDK 版本,平台版本,用户注册时间,用户活跃时间,用户所在城市等。
广播(所有人)
技术上广播很好理解,就是推送给所有安装的 App 的设备终端。
极光推送对广播有一个特殊的选项:延迟推送。这是个很有特色的功能,让推送在一定时长内平均分配,而不是在太短时间内完成,以免对 App 业务服务器造成太大的压力。
根据业务场景选择推送人群
以上以极光推送为例介绍了支持的推送人群类别。但是,任何技术都有一个使用场景的问题。开发者需要想清楚自己的使用场景,来选择适当的类别。
举一个比较极端的例子。极光推送曾经有一个开发者,其用户场景是,小学生手里有卡,小孩进学校门时需要刷卡。刷卡后,家长 App 上可以收到推送。我们注意到这个开发者是因为突然发现推送量暴增,这个推送量竟然来自于一个只有几万安装量的 App 。追查发现,这个应用每天推送大量的广播。为什么要推送那么多广播呢?与开发者一沟通,发现原来,他是每个学生有刷卡,都会做一次广播推送给所有用户,然后在 App 侧再去检查看只有我自己家小孩的刷卡才展示,其他都被过滤掉。
上面这个特例里,其实就是应该使用单设备推送时,错误选择了使用广播推送。
单设备推送
RegistrationID 与别名是设计用来单用户推送的。
如果别名只是在一个设备上被设置,则其效果与 RegistrationID 是类似的。
不同的是,一个别名是可以被设置到多设备上的。一个常见的场景是,把 App 的用户帐号 username 作为别名。一个 App 用户帐号可以在多设备上登录(大多数这样),就可以在多设备上绑定为别名。这样推送给这个别名,多设备上都收到。
由于别名的绑定关系保存在推送服务器上, App 业务上要做变更就不够灵活。所以,别名更适合于简单的使用场景,也是适合「懒」的开发者。而 App 想要有灵活性,建议使用 RegistrationID 的方式。
别名在使用时,有可能被误使用为 tag ,即大量的设备上都设置同一个别名,其实就是 tag 的使用方式。极光推送发现了不少 App 这样子用。
用户分群与标签
标签是个很灵活的分组方法,可以被用于业务强相关的各种场景。主要的种类有:订阅,用户属性。
订阅类,比如彩票 App 用于用户订阅不同彩票类型的最新开奖信息,阅读类 App 用于让用户订阅多个频道的最新资讯等。
用 tag 来标注用户的属性,比如性别、年龄段、喜好、关注等,也是个很常见的作法,这样推送时就可以基于这些属性来做。这也是精细化推送的基础。
事实上,很多标签被开发者定义为: App 版本,用户城市,使用语言等等。现在很多这类的 tags 可以不要了,只需要直接使用用户分群功能就可以了。
可能不是推送
其实还有一些场景,可能不是「推送」合适的场景,但很多开发者却尝试用 Push 来解决。
场景一:一个终端用户,需要向另外一个终端用户发消息。嗯,这是典型的 IM 场景,应该集成 IM SDK ,极光推送现在也提供 JMessage 来满足这个需求。
场景二:经常发生终端用户与服务端一对一沟通,比如电商类 App 一方面有订单状态需要发通知给用户,另一方面存在用户要找服务方咨询问题。这类对定位用户要求高,用 IM 来做相对开发起来简单。
总结来说, Push 更适合于服务方单方向发消息给终端用户。如果想要双方向沟通,用基于 IM 的模型更合适。
其实这里边有一个本质的问题, Push 本质是基于「设备」,而 IM 本质上是基于「用户」。某些 Push 服务提供了双向的能力(虽说这有点感觉怪怪的),但也是不太合适满足双向交流的需求的,或者说 App 用起来没有那么顺手。这方面,以后专门另外写文章来演绎得更清晰些。