阿里云主机折上折
  • 微信号
Current Site:Index > Push and Notifications (uni.push)

Push and Notifications (uni.push)

Author:Chuan Chen 阅读数:16960人阅读 分类: uni-app

Introduction to uni.push

uni.push is a cross-platform push service provided by uni-app, supporting iOS, Android, and Web platforms. It encapsulates the native push capabilities of each platform, allowing developers to implement push functionality by calling a unified API. uni.push supports various scenarios such as offline pushes, local notifications, and message passthrough, making it suitable for needs like message reminders, marketing pushes, and system notifications.

Push Service Configuration

Applying for Push Service Permissions

Before using uni.push, you need to apply for push permissions on each platform:

  1. iOS: Configure push certificates (development and production environments) in the Apple Developer Center.
  2. Android: Apply for app keys on various manufacturer push platforms (Huawei, Xiaomi, OPPO, vivo, etc.).
  3. Web: Use the browser notification API (requires user authorization).
// manifest.json configuration example
{
  "app-plus": {
    "distribute": {
      "ios": {
        "push": {
          "production": true,
          "devCert": "dev.p12",
          "prodCert": "prod.p12"
        }
      },
      "android": {
        "push": {
          "HW": {
            "appid": "Your Huawei App ID"
          },
          "XM": {
            "appid": "Your Xiaomi App ID",
            "appkey": "Your Xiaomi App Key"
          }
        }
      }
    }
  }
}

Client Initialization

Initialize the push service when the app launches:

// App.vue
export default {
  onLaunch() {
    uni.getPushClientId({
      success: (res) => {
        console.log('Client push identifier:', res.cid)
        // Send the CID to the server for storage
      },
      fail: (err) => {
        console.error('Failed to get push identifier:', err)
      }
    })
    
    // Listen for push messages
    uni.onPushMessage((res) => {
      console.log('Received push message:', res)
      if (res.type === 'click') {
        // User clicked the notification bar message
        this.handlePushClick(res)
      } else if (res.type === 'receive') {
        // Received passthrough message
        this.handlePushReceive(res)
      }
    })
  }
}

Push Message Types

Notification Bar Messages

Notification bar messages appear in the system notification center, and users can open the app by clicking them:

// Server push example (Node.js)
const push = require('uni-push')

push.send({
  platform: ['ios', 'android'],
  notification: {
    title: 'New Message Reminder',
    body: 'You have 3 unread messages',
    sound: 'default',
    badge: 3,
    extras: {
      path: '/pages/message/list',
      type: 'message'
    }
  },
  cid: ['Client push identifier 1', 'Client push identifier 2']
})

Passthrough Messages

Passthrough messages do not display notifications but are directly passed to the app for processing:

push.send({
  platform: ['ios', 'android'],
  message: {
    title: 'Silent Message',
    content: '{"action":"update","data":{"version":"1.2.0"}}',
    extras: {
      silent: true
    }
  },
  cid: ['Client push identifier']
})

Local Notifications

Local notifications triggered within the app do not require server involvement:

uni.createPushMessage({
  title: 'Local Notification',
  content: 'This is a locally generated notification',
  delay: 5, // Display after 5 seconds
  sound: 'default',
  extras: {
    path: '/pages/home/index'
  },
  success: () => {
    console.log('Local notification created successfully')
  }
})

Message Handling and Navigation

Handling Push Clicks

methods: {
  handlePushClick(res) {
    const extras = res.data.extras || {}
    if (extras.path) {
      // Navigate to the specified page
      uni.navigateTo({
        url: extras.path
      })
    }
    
    // Handle business logic based on message type
    switch(extras.type) {
      case 'message':
        this.updateUnreadCount()
        break
      case 'order':
        this.fetchLatestOrder()
        break
    }
  }
}

Message Arrival Statistics

// Track message arrival rate
uni.reportPushMsgArrival({
  msgid: res.data.msgid,
  success: () => {
    console.log('Message arrival reported successfully')
  }
})

Advanced Features

Tag and Alias Management

// Set user alias (replaces CID)
uni.setPushAlias({
  alias: 'user123',
  success: () => {
    console.log('Alias set successfully')
  }
})

// Add tags
uni.addPushTag({
  tags: ['vip', 'shanghai'],
  success: () => {
    console.log('Tags added successfully')
  }
})

Scheduled Pushes

// Server-side scheduled push
push.send({
  notification: {
    title: 'Daily Reminder',
    body: 'Remember to complete today’s tasks'
  },
  cid: ['Client push identifier'],
  time: '2023-12-31 20:00:00' // Specify the send time
})

Rich Media Notifications

// Android large image notification
push.send({
  platform: ['android'],
  notification: {
    title: 'New Product Launch',
    body: 'Click for details',
    style: {
      type: 1, // Large image style
      bigText: '...',
      bigPicPath: 'https://example.com/banner.jpg'
    }
  }
})

Common Issue Handling

Push Permission Check

uni.checkPushPermission({
  success: (res) => {
    if (!res.result) {
      // Guide the user to enable notification permissions
      this.showPermissionDialog()
    }
  }
})

Manufacturer Channel Adaptation

// Handle compatibility issues across different manufacturers
if (uni.getSystemInfoSync().platform === 'android') {
  // Special handling for Huawei devices
  if (uni.getSystemInfoSync().brand === 'HUAWEI') {
    this.adjustForHuawei()
  }
  // Special handling for Xiaomi devices
  else if (uni.getSystemInfoSync().brand === 'Xiaomi') {
    this.adjustForXiaomi()
  }
}

Push Performance Optimization

// Merge similar messages
let lastMessageTime = 0
uni.onPushMessage((res) => {
  const now = Date.now()
  if (now - lastMessageTime < 1000) {
    // Multiple messages received within 1 second, batch process
    this.batchUpdate()
    return
  }
  lastMessageTime = now
  // Normal processing
})

Push Strategy Design

User Segmentation Push

// Push different content based on user behavior
function getUserGroup(user) {
  if (user.lastLogin < Date.now() - 30*24*60*60*1000) {
    return 'inactive'
  } else if (user.orderCount > 5) {
    return 'vip'
  } else {
    return 'normal'
  }
}

const group = getUserGroup(currentUser)
push.send({
  notification: {
    title: group === 'inactive' ? 'Long Time No See' : 'Exclusive Offer',
    body: group === 'vip' ? 'VIP Exclusive Discount' : 'New User Benefits'
  },
  cid: [currentUser.cid]
})

A/B Testing Implementation

// Random group push
const variant = Math.random() > 0.5 ? 'A' : 'B'
const message = {
  A: {
    title: 'Limited-Time Discount',
    body: 'Up to 50% Off'
  },
  B: {
    title: 'New Product Launch',
    body: 'Buy Now'
  }
}

push.send({
  notification: message[variant],
  extras: {
    variant: variant
  },
  cid: [user.cid]
})

Data Statistics and Analysis

Push Effect Tracking

// Track user behavior
uni.onPushMessage((res) => {
  if (res.type === 'click') {
    const extras = res.data.extras || {}
    reportAnalytics('push_click', {
      msgid: res.data.msgid,
      type: extras.type,
      variant: extras.variant
    })
  }
})

Push Report Generation

// Server-side statistics example
async function generatePushReport(startDate, endDate) {
  const stats = await PushLog.aggregate([
    {
      $match: {
        createdAt: { $gte: startDate, $lte: endDate }
      }
    },
    {
      $group: {
        _id: '$campaign',
        sent: { $sum: 1 },
        arrived: { $sum: { $cond: [{ $eq: ['$arrived', true] }, 1, 0] } },
        clicked: { $sum: { $cond: [{ $eq: ['$clicked', true] }, 1, 0] } }
      }
    }
  ])
  
  return stats.map(item => ({
    campaign: item._id,
    arrivalRate: (item.arrived / item.sent * 100).toFixed(2) + '%',
    clickThroughRate: (item.clicked / item.arrived * 100).toFixed(2) + '%'
  }))
}

Security and Permission Control

Push Content Review

// Server-side content filtering
function filterPushContent(content) {
  const bannedWords = ['Sensitive word 1', 'Sensitive word 2']
  for (const word of bannedWords) {
    if (content.includes(word)) {
      throw new Error('Push content contains sensitive words')
    }
  }
  return content
}

User Unsubscription Handling

// Unsubscription management
uni.getPushSetting({
  success: (res) => {
    if (!res.notificationEnabled) {
      // User has disabled notifications
      this.showReEnableDialog()
    }
  }
})

// Unsubscribe from specific message types
uni.subscribePush({
  topic: 'promotion',
  subscribe: false, // Unsubscribe
  success: () => {
    console.log('Unsubscribed from marketing messages')
  }
})

Multi-Platform Differences Handling

iOS Special Configuration

// Handle iOS push limitations
if (uni.getSystemInfoSync().platform === 'ios') {
  // Request notification permission
  uni.requestPushPermission({
    success: (res) => {
      if (res.result) {
        console.log('Push permission granted')
      }
    }
  })
  
  // Clear badge count
  uni.setPushBadge({
    badge: 0
  })
}

Web Platform Adaptation

// Web platform notification handling
if (process.env.VUE_APP_PLATFORM === 'h5') {
  // Check browser notification support
  if (!('Notification' in window)) {
    console.log('This browser does not support notifications')
  } else if (Notification.permission === 'granted') {
    // Already authorized
  } else if (Notification.permission !== 'denied') {
    // Request permission
    Notification.requestPermission().then(permission => {
      if (permission === 'granted') {
        new Notification('Welcome Back')
      }
    })
  }
}

Debugging and Issue Troubleshooting

Push Log Recording

// Client-side log recording
uni.onPushMessage((res) => {
  console.log('Push message details:', JSON.stringify(res))
  this.savePushLog(res)
})

// Save push logs
savePushLog(pushData) {
  const logs = uni.getStorageSync('push_logs') || []
  logs.unshift({
    time: new Date().toISOString(),
    data: pushData
  })
  uni.setStorageSync('push_logs', logs.slice(0, 100)) // Keep the last 100 entries
}

Common Error Handling

// Error handling example
uni.getPushClientId({
  fail: (err) => {
    switch(err.code) {
      case 10001:
        console.error('Push service not initialized')
        break
      case 10002:
        console.error('Device does not support push')
        break
      default:
        console.error('Unknown error', err)
    }
  }
})

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.