推送通知不再是你的推送:Apple 与 Google 如何悄悄变成品牌与用户之间的"中介"

2026-05-28 33 预计阅读时间:1 分钟
来源:oschina.net AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:12 分钟

十年前,推送通知的架构很简单——你的服务器把 JSON 打包,丢给 APNs 或 FCM 的端点,手机亮一下,用户点开。传输层只管投递,不关心内容。但 Jacques Corby-Tuech 最近的分析指出:这条管道正在被重新定义。Apple 和 Google 不再只做"邮差",它们正在成为品牌与用户之间的主动中介——筛选、重组、甚至用 AI 概括你发出的每一条消息。

这个转变和电子邮件的遭遇如出一辙:SMTP 本是开放协议,但 Gmail 的优先级收件箱、智能分类、Promotions 标签,已经让发件人失去了对呈现方式的控制。推送通知正在走同一条路。

从传输层到中介层:发生了什么

传统推送流程是线性的:

你的业务服务器 → APNs / FCM → 用户设备 → 通知中心展示

你控制标题、正文、图标、点击行为。平台只负责加密投递和送达确认。

但近两年,两端都在加"中间逻辑":

  • Apple:iOS 16 引入 Live Activities;iOS 18 加入通知摘要(AI 将多条通知合并成一句话);通知分组规则由系统自动决定;App 的推送需要通过"重要通知"审核才能突破默认静默。
  • Google:Android 13 起要求运行时通知权限(POST_NOTIFICATIONS);FCM 控制台提供"主题订阅"和 A/B 测试分发能力;Pixel 设备上的通知摘要同样由 Gemini 驱动。

平台不再只是"把你的 JSON 送到设备"。它在读你的内容、改你的呈现、替用户做过滤决策

中介化的三个具体维度

1. 内容被 AI 重写

iOS 18 的通知摘要功能会把你精心写的"您的订单已发货,预计周三送达"压缩成"2 条订单更新"。你花了时间设计的文案,用户看到的可能是 AI 的一句话概括。品牌语调、行动引导(CTA)、紧急程度——全部被抹平。

2. 送达权被平台审核

Apple 的"Critical Alerts"(重要通知) entitlement 需要申请并审核。没有它,你的紧急通知在专注模式下会被静默。Google 的 POST_NOTIFICATIONS 权限让用户可以一键关掉所有推送——而你的 App 没有任何二次触达通道。

3. 分组与排序由系统决定

通知分组规则从开发者手中转移到操作系统。Android 的通知渠道(Notification Channels)和 iOS 的分组线程(threadIdentifier)给了开发者一些配置空间,但最终排序、折叠、摘要逻辑由平台算法决定。你的"限时优惠"可能被塞进一个叫"促销"的折叠组,用户永远不展开。

实际影响:一条推送的完整生命周期

下面用代码展示当前推送的完整发送流程,你可以看到平台在哪些环节插入了中介逻辑:

FCM 示例:发送一条带分类的推送

# fcm_push_demo.py
# 运行前:pip install firebase-admin
# 需要下载 Firebase 项目的服务账号 JSON 文件

import firebase_admin
from firebase_admin import credentials, messaging

# 1. 初始化——平台已经在这里介入:你的项目必须通过 Firebase 注册
cred = credentials.Certificate("service-account-key.json")
firebase_admin.initialize_app(cred)

# 2. 构造消息——注意 notification 和 data 的区别
#    notification 字段的内容会被系统自动展示,受摘要/分组规则控制
#    data 字段由你的 App 自行处理,但不会在通知中心直接显示
message = messaging.Message(
    notification=messaging.Notification(
        title="您的订单已发货",
        body="预计周三送达,点击查看物流详情",
    ),
    data={
        # 这些数据你的 App 可以在后台读取,但用户在通知中心看不到原文
        "order_id": "ORD-20250618-001",
        "tracking_url": "https://track.example.com/ORD-20250618-001",
        "urgency": "high",  # 自定义字段,但平台不认——它有自己的优先级算法
    },
    android=messaging.AndroidConfig(
        # 3. Android 通知渠道——你必须预先在 App 中注册渠道
        #    用户可以在系统设置中关闭某个渠道,你的推送就永远送达不了
        notification_channel_id="order_updates",
        priority="high",
    ),
    apns=messaging.APNSConfig(
        payload=messaging.APNSPayload(
            aps=messaging.Aps(
                # 4. iOS threadIdentifier 决定分组,但摘要逻辑由系统 AI 控制
                thread_id="order_updates",
                # 5. 如果要突破专注模式,需要 Critical Alerts entitlement
                #    普通推送在专注模式下会被静默
                # sound="default",  # 普通声音
            ),
        ),
    ),
    token="<目标设备的 FCM 注册令牌>",
)

# 6. 发送——FCM 可能因为用户关闭权限而返回错误
#    你无法知道通知最终是否被用户看到
try:
    response = messaging.send(message)
    print(f"发送成功,消息 ID: {response}")
except messaging.UnregisteredError:
    print("设备令牌已失效——用户可能卸载了 App 或关闭了通知权限")
except messaging.SenderIdMismatchError:
    print("发送者 ID 不匹配——你的服务账号不属于目标项目")

关键观察点标注在注释里。每一步,平台都在做决策:渠道是否开启、分组如何折叠、摘要怎么压缩、专注模式下是否放行。开发者能控制的范围正在缩小。

用 curl 直接调用 APNs:看到更裸的传输层

如果你绕过 FCM,直接调用 APNs 的 HTTP/2 端点,传输层的本质更清晰——但中介逻辑依然在设备端生效:

# 直接调用 APNs(需要 .p8 token 签名,此处仅展示请求结构)
# 实际运行需要:openssl 生成 JWT,curl 支持 HTTP/2

# 生成 JWT token(简化示例,生产环境应使用库)
JWT_HEADER=$(echo -n '{"alg":"ES256","kid":"YOUR_KEY_ID"}' | base64)
JWT_CLAIM=$(echo -n '{"iss":"YOUR_TEAM_ID","iat":'$(( $(date +%s) ))'}' | base64)

# 发送推送
curl -v \
  --http2 \
  -H "authorization: bearer $JWT_HEADER.$JWT_CLAIM.$JWT_SIGNATURE" \
  -H "apns-topic: com.yourapp.bundleid" \
  -H "apns-push-type: alert" \
  -d '{"aps":{"alert":{"title":"订单已发货","body":"预计周三送达"},"thread-id":"order_updates"}}' \
  https://api.push.apple.com/3/device/<DEVICE_TOKEN>

APNs 的 API 本身是纯粹的传输——你发 JSON,它投递。但到达设备后,iOS 的通知引擎会接管:分组、摘要、专注模式过滤。中介化不在传输协议里,而在操作系统的通知框架里

开发者可以做什么:一份应对清单

中介化是不可逆的趋势。与其抱怨平台"抢了控制权",不如调整策略:

维度 当前风险 应对思路
AI 摘要抹平文案 品牌语调消失 把关键信息放在 data 字段,App 内展示完整内容;通知只做"钩子"
通知权限被用户一键关闭 失去唯一触达通道 建立 App 内消息中心 + 邮件 + SMS 的多通道冗余
专注模式静默普通推送 紧急消息无法送达 申请 Critical Alerts entitlement(Apple)或使用 full-screen intent(Android)
分组折叠降低可见性 营销推送被永久折叠 减少低价值推送频率,让每条通知都值得单独展示
渠道管理权在用户 单个渠道被关闭 在 App 设置中引导用户管理渠道偏好,而非让用户去系统设置里盲关

最小可行策略:把推送当成"钩子"而非"完整消息"

# 改造后的推送策略:通知只做提醒,完整内容在 App 内展示

message = messaging.Message(
    notification=messaging.Notification(
        # 简短标题——即使被 AI 概括,核心信息"有新消息"仍然保留
        title="订单更新",
        body="查看详情",  # 不在通知正文放关键信息,因为可能被摘要吞掉
    ),
    data={
        # 完整内容在这里,App 打开后自行渲染
        "type": "order_shipped",
        "order_id": "ORD-20250618-001",
        "estimated_delivery": "2025-06-21",
        "tracking_url": "https://track.example.com/ORD-20250618-001",
        "full_message": "您的订单 ORD-20250618-001 已发货,预计6月21日送达。点击查看实时物流。",
    },
    android=messaging.AndroidConfig(
        notification_channel_id="order_updates",
    ),
    apns=messaging.APNSConfig(
        payload=messaging.APNSPayload(
            aps=messaging.Aps(
                thread_id="order_updates",
                mutable_content=1,  # 允许 App 修改通知内容(iOS 10+)
            ),
        ),
    ),
    token="<DEVICE_TOKEN>",
)

核心思路:通知正文只承担"来 App 里看"的钩子功能,所有品牌化内容、CTA、详细信息都放在 data 字段中由 App 自行展示。这样即使 AI 把通知摘要成"3 条更新",用户点进 App 后仍然能看到你设计的完整体验。

写在最后

推送通知的中介化和电子邮件的中介化有一个关键区别:邮件至少还有 SMTP 这个开放协议做底层,你可以自建服务器、绕过 Gmail。但推送通知的传输层本身就是封闭的——APNs 和 FCM 是唯一通道,没有替代方案。

这意味着开发者的议价能力比邮件时代更弱。平台的每一个新功能——AI 摘要、分组算法、权限模型——都是不可选择、不可绕过的。你能做的不是对抗中介,而是在中介的规则下设计最优的信息架构:推送做钩子,App 内做完整体验,多通道冗余保送达。

下一次你在写推送文案时,先问自己一个问题:如果这条通知被 AI 压缩成两个字,用户还能知道该做什么吗? 如果答案是不行,你的信息架构就需要重新设计。


相关推荐