內(nèi)部爆料,推送服務(wù)的那些“坑”
隨著移動(dòng)互聯(lián)網(wǎng)行業(yè)發(fā)展越來越成熟,各種各樣的開發(fā)工具與標(biāo)準(zhǔn)化的解決方案,正在急速降低互聯(lián)網(wǎng)產(chǎn)品的開發(fā)成本。推送服務(wù)儼然已成為移動(dòng)開發(fā)中的標(biāo)配服務(wù)。作為業(yè)務(wù)唯一能夠主動(dòng)touch用戶的手段,推送服務(wù)對(duì)于app拉新、拉活、引流、保活都有著非比尋常的意義。
然鵝,作為一個(gè)多年奮戰(zhàn)在“技術(shù)客服”一線的產(chǎn)品經(jīng)理,我想說對(duì)于推送服務(wù)——多的是,你不知道的事~~
接下來我就以小米推送為例,跟各位開發(fā)者(產(chǎn)品/運(yùn)營(yíng)同學(xué))簡(jiǎn)單講講在和形形色色的開發(fā)者對(duì)接過程中,我所見過的最隱蔽、最難躲的坑。
文章分別從四個(gè)方面總結(jié)了關(guān)于推送服務(wù)過程中隱蔽的坑,會(huì)通過兩期的內(nèi)容分別呈現(xiàn)給大家,希望可以給大家一些警示。
本期,我們先從注冊(cè)和注銷兩方面來進(jìn)行探討~
1 、一切的開始:設(shè)備注冊(cè)
所有的推送服務(wù)使用的第一步,都是注冊(cè)設(shè)備。其實(shí)原因和目的都是顯而易見的,因?yàn)橥扑捅旧硎且粋€(gè)點(diǎn)對(duì)點(diǎn)的行為,每臺(tái)設(shè)備的客戶端都需要與服務(wù)端建立一個(gè)獨(dú)立的長(zhǎng)連接用于收發(fā)消息。因此,推送服務(wù)需要對(duì)每個(gè)設(shè)備進(jìn)行標(biāo)示。
各家推送服務(wù)的注冊(cè)接口叫法都不同,但有兩點(diǎn)是一樣的:
1)這一接口均為客戶端接口
2) 通過調(diào)用接口后均會(huì)生成一個(gè)per app&per 設(shè)備的唯一標(biāo)示
以小米推送為例,客戶端注冊(cè)推送的接口叫做registerPush,注冊(cè)成功后,會(huì)生成一個(gè)regID,regID在推送系統(tǒng)中是全局唯一的,mipush通過一套復(fù)雜的加密算法,保證每個(gè)app在每臺(tái)設(shè)備上都不一樣。
介紹完背景知識(shí),我們來講講在注冊(cè)設(shè)備這個(gè)看似最簡(jiǎn)單最基礎(chǔ)的動(dòng)作中隱藏的坑:設(shè)備注冊(cè)的時(shí)機(jī)。
由于pushSDK需要有客戶端工程師手動(dòng)集成到app之中,registerPush的方法也需要客戶端自行調(diào)用才能完成注冊(cè)行為。因此,注冊(cè)行為的時(shí)機(jī)就非常重要。
那么從產(chǎn)品層面,怎樣設(shè)計(jì)注冊(cè)推送的時(shí)機(jī)呢?
由于不同的產(chǎn)品之間,業(yè)務(wù)形態(tài)千差萬別。所以很難總結(jié)一條明確的規(guī)定來指導(dǎo)使用者去注冊(cè)推送。但每位產(chǎn)品經(jīng)理在設(shè)計(jì)推送的使用邏輯時(shí),一定要將這一點(diǎn)想到前邊,了解app注冊(cè)推送的時(shí)機(jī),結(jié)合業(yè)務(wù)邏輯去決策注冊(cè)推送的時(shí)機(jī)。以免為以后推送的使用埋下“神坑”。
舉個(gè)簡(jiǎn)單的例子來說明一下吧:
某直播app,產(chǎn)品邏輯中有這樣一條限制:只有登陸之后才能看到內(nèi)容。即登錄是強(qiáng)制動(dòng)作。
這時(shí)候注冊(cè)應(yīng)該在什么時(shí)機(jī)呢?是在登錄前還是登錄后呢?
其實(shí)這個(gè)問題沒有標(biāo)準(zhǔn)答案,要通過業(yè)務(wù)邏輯來進(jìn)行設(shè)計(jì)。如果推送體系是基于賬號(hào)設(shè)計(jì)的,只有登錄完成之后,才能有賬號(hào),那么在登陸后注冊(cè)推送聽上去比較合理,沒有登錄的用戶不作為自己的推送目標(biāo);如果推送不基于賬號(hào),而是基于設(shè)備,及時(shí)未登錄的設(shè)備,也希望能夠接受推送消息。那么注冊(cè)時(shí)機(jī)應(yīng)該在用戶登錄之前。即app被用戶打開即可喚起推送。
2 、不要隨便注銷
一般的推送服務(wù)都會(huì)提供注冊(cè)(registerPush)和注銷(unregisterPush)兩種接口,這兩種接口都是客戶端能力。用于開啟和關(guān)閉推送功能。需要注意的是:調(diào)用注銷接口后,之前注冊(cè)的設(shè)備ID(regID)就失效了,無法繼續(xù)使用。即使重新注冊(cè),也會(huì)生成新的設(shè)備ID。
所以注冊(cè)行為是一種不可逆的行為,僅適用于需要完全終止推送服務(wù)的場(chǎng)景。
如果一直頻繁的調(diào)用注冊(cè)和注銷接口,會(huì)有什么風(fēng)險(xiǎn)呢?
我們?cè)倥e一個(gè)栗子:
還是拿剛才的直播app舉例,需求是如果用戶登出,則不再向該設(shè)備推送消息。客戶端邏輯為:用戶登陸后,調(diào)用registerPush接口;用戶注銷后,調(diào)用unregisterPush接口。按照以上行為,每次用戶進(jìn)行登錄和登出操作,均會(huì)生成新的regID。這種行為直接導(dǎo)致無效的regID會(huì)越來越多。推送ID體系變得臃腫復(fù)雜。
因此,如果只是希望暫時(shí)停止推送或關(guān)閉推送能力。應(yīng)當(dāng)使用別的方式,而不是直接注銷推送。各家基本都提供了暫停推送的接口。
以mipush為例:
小米推送客戶端SDK中提供了兩種方式可以控制推送的使用或恢復(fù)使用。
1)設(shè)置推送接受時(shí)間(setAcceptTime):這種方式可以自由控制設(shè)備每天(00:00-23:59)允許接收推送的時(shí)間,達(dá)到停止/恢復(fù)推送的目的。
詳情如截圖:
舉個(gè)栗子:夜間不希望用戶收到推送/用戶可自主選擇接受推送的時(shí)間
2) 關(guān)閉/打開推送(enable/disablePush):與上邊的方式不同,設(shè)置acceptTime后,長(zhǎng)連接并未斷開。但設(shè)置disablepush之后,該設(shè)備的長(zhǎng)連接也將斷開,只保留regID的有效性。
詳情如截圖:
舉個(gè)栗子:某些情況下處于為設(shè)備省電省流的考慮,希望長(zhǎng)連接斷開,但保留推送能力,則可使用這一方法。
3、正確認(rèn)識(shí)送達(dá)率
送達(dá)率是每個(gè)使用推送的開發(fā)者最關(guān)心的數(shù)據(jù)指標(biāo)之一,也是衡量一個(gè)推送服務(wù)靠不靠譜的關(guān)鍵指標(biāo)。
然鵝,怎樣才算送達(dá)率的正確打開方式?我以小米推送為例來解釋一下這個(gè)問題~
首先需要說明的是推送服務(wù)送達(dá)率的計(jì)算方式:
分子比較容易理解,就是本次推送真正送達(dá)的設(shè)備數(shù)。
分母則是本次推送請(qǐng)求所覆蓋的有效的設(shè)備數(shù):如果目標(biāo)對(duì)象的選取是所有用戶,那分母就是歷史上所有激活過推送服務(wù)的有效設(shè)備數(shù);如果是按照標(biāo)簽選取的,那分母是歷史上所有訂閱過這個(gè)標(biāo)簽的有效設(shè)備數(shù);如果是按照別名或者regID來選取,那么分母就是所請(qǐng)求的所有合法的別名或regID。其中,設(shè)備的有效性是通過如下規(guī)則來判斷的:如果應(yīng)用有以下幾種行為:
1)調(diào)用unregisterPush,
2) 用戶主動(dòng)卸載,
3)超過3個(gè)月都沒有和小米服務(wù)器建立過長(zhǎng)連接,則會(huì)判定設(shè)備失效。
4)設(shè)置alias失敗等
按照這種計(jì)算方式,會(huì)有如下幾個(gè)影響送達(dá)率的因素:
① 應(yīng)用的留存率。
已經(jīng)卸載了app的設(shè)備,肯定是推送不到的,但按照目前的計(jì)算方式,不少卸載設(shè)備(尤其是)都會(huì)被計(jì)入分母(計(jì)劃推送數(shù))當(dāng)中。
②應(yīng)用所在設(shè)備的聯(lián)網(wǎng)情況。
如果在消息有效期內(nèi),設(shè)備一直不聯(lián)網(wǎng),那消息也是不能送達(dá)的,但也會(huì)被計(jì)入分母當(dāng)中。
③消息的有效期。
有效期越短,在有效期內(nèi)聯(lián)網(wǎng)的設(shè)備數(shù)勢(shì)必就越少,因此送達(dá)率會(huì)隨之下降。
④目標(biāo)設(shè)備的選取。
如果選取的是全量用戶,那其送達(dá)率肯定會(huì)比按照用戶聯(lián)網(wǎng)情況精準(zhǔn)提取目標(biāo)設(shè)備(如選取7天內(nèi)有過打開應(yīng)用行為的用戶)要低。
4 APNs服務(wù)的“神坑”
作為一個(gè)有追求、有態(tài)度的推送服務(wù),支持全平臺(tái)是基本的專業(yè)能力。可是面對(duì)蘋果這個(gè)神一樣的廠商,再牛叉的平臺(tái)都得俯首帖耳,遵從人家的規(guī)定。
市面上提供推送服務(wù)的公司在面對(duì)蘋果時(shí)候,基本都會(huì)采取相同的做法:
集成APNs(Apple Push Notification service)
APNs是蘋果官方提供的推送服務(wù),由于蘋果閉源的生態(tài),所有開發(fā)者都只能使用這種方式來實(shí)現(xiàn)推送能力,強(qiáng)如微信也不例外。同時(shí),無論是Android和iOS(包括WinPhone),推送服務(wù)的服務(wù)端接口的定義和使用方法保持一致,在結(jié)合業(yè)務(wù)邏輯使用的過程當(dāng)中,客戶端的差異可以透明化。
今天在這里并不想展開講APNs,只想吐槽一下偉大的蘋果……
但凡搞過iOS開發(fā)的同學(xué),基本都面對(duì)過同一個(gè)難題:無法獲取設(shè)備的唯一標(biāo)示。唯一用于標(biāo)識(shí)設(shè)備的DeviceToken也會(huì)經(jīng)常發(fā)生變化。
這一點(diǎn)其實(shí)也很好解釋:如果開發(fā)者能唯一標(biāo)示設(shè)備,對(duì)用戶而言將會(huì)有很大的隱私風(fēng)險(xiǎn)。
開發(fā)者可能感觸不深,然鵝對(duì)于推送服務(wù)而言,這幾乎是令人抓狂的:無法拿到設(shè)備的唯一標(biāo)示,該怎么做推送呢!
Mipush在這方面做了非常多的努力和嘗試,包括使用iOS的key chain能力去存儲(chǔ)設(shè)備標(biāo)識(shí)……
然鵝,最近我看到了這樣的一條新聞【截圖來自MrPeak雜貨鋪】:
簡(jiǎn)而言之,獲取唯一標(biāo)示這件事情基本已經(jīng)被蘋果趕盡殺絕了……
無論怎樣,路還得走,產(chǎn)品還要不斷發(fā)展,相信我們后面會(huì)有更好的解決辦法,幫助廣大開發(fā)者解決這些難題~
以上就是我做推送的一點(diǎn)心得,希望能為你提供一點(diǎn)點(diǎn)幫助~
【本文是51CTO專欄“小米開放平臺(tái)”原創(chuàng)文章,“小米開放平臺(tái)”微信公眾號(hào)xiaomideveloper】