我和极光的那些事儿 | 基于 PHP&Cordova — 推送实现及角标的设置

没想到做 PHP 还会接触这方面的东西,感觉风马牛不相及,在这里碰头了。从 PHP api到 Cordova 搭建打包 App再到里面的极光推送和小红点的数值,真是秃了半边顶。(话说回来,我们 BOSS 和个推可是校友,我可是力排众议,毅然决然选择了极光推,滑稽.jpg)
--萌新寄语

本篇主要介绍 Cordova 和 PHP 配合,完成极光推送消息( iOS 集成推送的证书申请, PHP 推送代码实现)及角标数值(badgeNum)的自我实现。多以截图为主,直击老铁痛点。

这边主要介绍 jpush ios 推送证书的申请,申请好了的,可以直接跳下面 PHP 部分

先介绍下我的环境,我只用到了 jpush。所以申请极光账号还是很简单的,不需要什么身份认证。
一. 创建应用后的操作

创建成功后的信息

其中 AppKey 是 Cordova 安装 jpush 插件的必须 也是后面推送的必须(还有隐藏的
Master Secret)

  • 下面就可以设置推送的相关信息了

推送设置页面

安卓的无脑操作这里就不介绍了
注意包名一定要统一 避免不必要的麻烦,这里详细介绍下 iOS 的证书设置(鉴权方式为 证书)我这里用的是个人开发者账号 $99 没有证书、Mac 的之类的兄弟姐妹就早点儿下班休息吧航

首先需要用你的开发者账号登陆苹果开发者中心

  1. 然后打开这个惨绝人寰的页面


    找到这个页面详见url
  2. Development 顾名思义即开发证书


    image.png
  3. 点击加号后出现的页面 选中开发的按钮后就可以下一步 continue 了


    上面的就是开发 下面的是生产 一个个来吧
  4. 选择以后继续 continue


    image.png
  5. 一直 continue 到这个页面 选择签名 这个时候就需要 Mac 的钥匙串去请求签名证书了 这一步先放在这里


    image.png
  6. Mac 请求证书


    image.png
  7. 请求成功之后,保存在本地,创建一个这个包名的文件夹 方便区分


    image.png
  8. 回到已经打开的 苹果开发者中心 选择刚才存到本地的证书 down 下来
    image.png

    下载下来的 .cer 后缀的文件就是我们要的了。拖到钥匙串中打开
    按流程走就行了

    下面就是导出 .p12 的文件了!!!! 盼星星盼月亮 终于盼到这一步了
    部分情况会出现不能导出 .p12 没有这个选项,请把证书拖到登陆里面,再次尝试
  9. 走完下面这一步就大功告成了


    注意事项 见图
  10. 都是明白人儿 放进去就行了。虽然下面有提示 是否将生产证书用于开发环境,想都别想,趁热把另一个证书申请了吧
    image.png
  11. 开发证书和生产证书操作是一毛一样的 两个同时操作也行 也没意见
    哝 就上面的区别
  12. 最终结果


    还不是美滋滋


PHP 端处理 badge 的思路的自我实现

关于推送的信息,一定要多看极光的控制台。reg_id和msg_id 平台信息等都在上面。方便你去查找错误信息


1. 是要区分你是什么推送方式 PHP接口处理推送当然是API喽,还用想

几个常用的信息,给大家划了出来

之前一直不懂 Jpush 服务器的角标值是怎么玩的,现在大概明白了。关于推送的 badge数量在我上面截图红圈的 badge 参数。这样我们不要自己去计算角标值,根据下面的两个接口定义 就可以根据用户是否点击,在原有的基数上去对应的增加减少即可 但是如果我们想要看到消息日志的话和推送日志方便自己管理的话 就要自己去建表存储状态了

客户端设置角标.png

大概思路是 这里我用了三张表去控制 大概实现了角标的核销。


数据表的设计
  • 用户每一次登陆都会去获取一下设备的 id,也就是极光的 registration_id 。(防止设备 ID 改变,极光介绍,或者用户更换手机,能准确的推送到该设备)
  • message 表主要做存储发送消息的记录。方便后台管理员了解曾经推送过得信息。
  • message_log 表主要就是存储推送的消息日志(用户太多的话肯定要优化数据表的,暂时不做考虑),根据表里的 status 就可以判断是否已读,用户每次点击消息详情页都要去访问下接口去修改 status 的状态,从而完成核销。核销的基础是该用户的 id 和消息 id,因为这两个都是唯一的。
    PHP 逻辑代码简单的封装了一下详见 jpushPHPdemo
    protected function pi_push($member_id,$content,$badgeNum,$array){
        try {
            // 配置引入
            $app_key         = PI_Config::APP_KEY;
            $master_secret   = PI_Config::MASTER_SECRET;
            // use jpush
            $client  = new JPush($app_key, $master_secret);
            $response = $client->push()
                        ->setPlatform("all")
                        ->addRegistrationId( $member_id )
                        ->iosNotification( $content, array(
                            'sound' => 'sound.caf',
                            'badge' => "$badgeNum" + 1,
                            'content-available' => true,
                            'mutable-content' => true,
                            'extras' => $array
                        ))
                        ->androidNotification( $content, array(
                            // 'title' => ,
                            'extras' => $array
                        ))
                        ->options(array(      
                       // !!!! apns_production:这里我试过去掉 option参数 以为默认推送生产环境,其实不然。需要生产环境的推送的时候,最好指定!!! 
                       // True 表示推送生产环境,False 表示要推送开发环境;如果不指定则默认为推送生产环境
                            'apns_production' => true,
                        ))
                        ->send();
            if ( $response['http_code'] == 200) {
                return $response['body']['msg_id'];
            }else{
                return false;
            }
        } catch (\JPush\Exceptions\APIConnectionException $e) {
                return false;
        } catch (\JPush\Exceptions\APIRequestException $e) {
                return false;
        }
    }

下面执行推送的代码

// 手动推送的设置
    public function post_push( $request ){
        $res['title']       =   $request['title'];          // 推送的标题
        $res['content']     =   $request['content'];    // 推送的内容
        $res['remark']      =   $request['remark'];    // 推送的备注
        $res['create_date'] =   date( "Y-m-d H:i:s" );
        // 推送类型
        $push_type  =   $request['push_type'];  
        // 推送前插入 推送记录表 (WordPress的mysql insert方法)
        if ( $push_type === '0' ) {
            $info = $this->wpdb->insert(
                $this->pi_message,
                $res,
                array( '%s', '%s', '%s' )
            );
        }
        // 插入成功 推送并插日志表
        if( $info ){
            // 查找所有设备ID 上面接受过 每次登陆或者注册 都要重新获取一下reg_id
            $find_sql   = "SELECT device_id FROM $this->pi_bindinguser";
            //设备ID的数组集合
            $total_user = $this->wpdb->get_results( $find_sql, ARRAY_A  );
            // 找到所有的设备id 发送数据
            foreach ($total_user as $key => $value) {
                // 每个设备id
                $device_id  =    $value['device_id'];
                // 通过设备id 去查找 member_id 从而计算该用户的未读和已读
                $sql        =   "SELECT member_id FROM $this->pi_bindinguser WHERE device_id = ". " '$device_id' ";
                // 计算badge_num的数值
                $member_id   =  $this->wpdb->get_var( $sql );
                // 获取当前的状态为零 未读取的小红点
                $total_sql  =   "SELECT count(id) FROM $this->pi_message_log WHERE member_id = $member_id AND status = 0" ;
                //如果该用户消息为空的话 即默认为0开始
                $badge_num  =   empty( $this->wpdb->get_var( $total_sql ) ) ? '0' :  $this->wpdb->get_var( $total_sql );
                $msg_id = $this->pi_push($device_id,$res['content'],$badge_num,$array);
                // var_dump( $msg_id );
                //推送成功之后 拿到msg_id 和 member_id 也就是消息id和用户id 两个对应的数据唯一 去存入消息列表 做核销使用
                if( $msg_id ){
                    $time = date( "Y-m-d H:i:s" );
                    $info = $this->wpdb->insert(
                        $this->pi_message_log,
                        array('member_id'=>$member_id,'msg_id'=>$msg_id,'content'=>$res['content'],'create_date'=>$time,'push_type'=>$push_type),
                        array( '%s', '%s', '%s', '%s', '%s' )
                    );
                }
            }
            return PI_Response::init( 0 );
        }else{
            return PI_Response::init( 1003 );
        }

    }

到此 推送和本地计算角标值也就差不多了。客户端的 badge 改动就要他们自己去掉 jpush 的接口了。因为每查看一次消息就去访问接口的,这样的话客户端和服务端的角标值的数值就对应上了,有点像 ajax 的无刷新删除


我是用蒲公英做的内测版 App 发布的。事先打包了 ipa 。这种情况的推送,必须要生产证书,也就是上面说的'apns_production' => true,

多看文档


推送成功的条件:设备id、正确的 AppKey master secret 、环境和对应的证书是否一致等。重要的事情说三遍 多看推送历史详情和社区

推送成功的前提


做完一套流程到后面才发现不需要自己控制消息日志,调用 jpush 的接口就可以去完成角标数值的增删设置、显示对应的小红点。我问老大,我们这样做是不是多余的。老大:相信极光,也相信我们自己。


「本文系极光征文 | 写写文章就能赢 Filco,岂不美滋滋的参赛文章」

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容