Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Trigger Push Prompt Programmatically

This guide explains how to implement smart push notification prompts in MobiLoud apps using the available APIs and best practices. For the purpose of this guide, we will create a button that is only displayed under the correct conditions, and that when clicked, triggers the push notification prompt.

Setup Flow Overview

Here's the basic flow for implementing a push notification button:

  1. Configure your app to disable automatic prompts (iOS_Enable_Push_Notifications: false)
  2. Wait for page load and MobiLoud APIs to be ready
  3. Check if button should be shown (user in app + notifications disabled)
  4. Display button with appropriate text
  5. Set up real-time listener for subscription status changes
  6. Handle button clicks to trigger push prompt
  7. Update button text based on subscription status changes

App Configuration

To have full control over when push prompts appear, you should configure your MobiLoud app to disable the default push prompt that shows immediately when the app opens. Add these parameters to your app configuration:

{
  "App_Permissions": {
    "iOS_Enable_Push_Notifications": false,
    "Android_Enable_Location": false
  }
}

Setting iOS_Enable_Push_Notifications to false disables the automatic push prompt that MobiLoud normally shows on app launch. This gives you complete control over when and how to present the push notification request to your users.

MobiLoud APIs & Objects

1. App Detection

Check if user is in MobiLoud app:

function isInApp() {    
	return navigator.userAgent.toLowerCase().includes('canvas');
}

MobiLoud apps inject "canvas" into the user agent string. This is how we determine if the user is accessing your website from within the app or from a regular browser. Push prompts should only appear when users are in the app context, since regular browsers don't have access to the native push notification functionality.

2. Push Subscription Status

Get current status:

function isPushEnabled() {
    try {
        return !!(window.mobiloudAppInfo && window.mobiloudAppInfo.pushSubscribed);
    } catch (e) {
        return false; // Assume disabled if can't read
    }
}

MobiLoud injects an object called mobiloudAppInfo into the DOM that allows you to pull certain details about the user, including their current push notification subscription status. The pushSubscribed property is a boolean that tells you whether the user has already enabled push notifications for your app. This is super useful because you don't want to keep asking users who have already subscribed!

Object: window.mobiloudAppInfo.pushSubscribed

  • Type: Boolean
  • Purpose: Current push notification subscription status

3. Real-time Status Changes

Listen for status changes:

// Override the global callback
window.mlPushStatusChanged = function(isSubscribed) {
    console.log('Push status changed:', isSubscribed);
    // Update your UI here
    updatePromptVisibility(isSubscribed);
};

Here's the thing - we can't update that mobiloudAppInfo object in real-time when the user's subscription status changes. This is due to limitations in the WebView. So instead, MobiLoud triggers a global function called mlPushStatusChanged whenever the subscription status changes. This makes it super easy for you to update your UI elements immediately when the user enables or disables notifications, giving them a much smoother user experience. No need to constantly check the status or refresh the page!

Function: window.mlPushStatusChanged(isSubscribed)

  • Type: Global callback function
  • Parameter: isSubscribed (boolean)
  • Triggered: When user enables/disables notifications
  • Use: Real-time UI updates without polling

4. Trigger Push Prompt

Show native permission dialog:

function triggerPushPrompt() {
    // Only trigger if in app context
    if (isInApp()) {
        nativeFunctions.triggerPushPrompt();
    }
}

This function triggers the native OS-level permission dialog that asks the user to enable push notifications. It's the actual system prompt that appears on iOS and Android devices.

Function: nativeFunctions.triggerPushPrompt()

  • Purpose: Shows OS-level permission dialog or settings redirect
  • Automatic fallback: Handles platform limits automatically

API Availability & Timing

Waiting for APIs to Load

The nativeFunctions object and mobiloudAppInfo are not available immediately when the page loads. The app needs time to initialize and inject these APIs into your webpage. Here's how to handle this:

Option 1: Polling Method

function waitForNativeFunctions(callback, maxAttempts = 50) {
    let attempts = 0;
    
    function check() {
        attempts++;
        
        // Check if APIs are ready
        if (typeof nativeFunctions !== 'undefined' && window.mobiloudAppInfo) {
            callback(); // APIs ready, proceed
        } else if (attempts < maxAttempts) {
            setTimeout(check, 100); // Try again in 100ms
        }
        // Stop after 5 seconds (50 × 100ms)
    }
    
    check();
}

Option 2: Event-based approach

// Wait for page to load, then start checking
document.addEventListener('DOMContentLoaded', function() {
    waitForNativeFunctions(() => {
        setupPushPrompt();
    });
});

This ensures your code doesn't try to access APIs before they're available, which would cause errors.

Platform Limitations & Automatic Fallback

How Platform Limits Work

Both iOS and Android have built-in restrictions on how many times an app can show the push notification permission prompt:

  • iOS: Allows only a limited number of permission requests per app installation
  • Android: Similar restrictions that vary by Android version

Automatic Fallback Handling

The good news is that nativeFunctions.triggerPushPrompt() handles these limits automatically! When the platform limits are reached, instead of showing the native system dialog, it will automatically display a different prompt that directs users to manually enable notifications through their device settings.

You don't need to detect or handle this yourself - just call triggerPushPrompt() and the function will either show the native dialog or the settings redirect as appropriate.

Complete Implementation Example

class PushNotificationButton {
    constructor() {
        this.button = null;
        this.init();
    }
    
    init() {
        // Wait for page to load
        document.addEventListener('DOMContentLoaded', () => {
            this.setup();
        });
    }
    
    setup() {
        // Wait for MobiLoud APIs to be available
        this.waitForNativeFunctions(() => {
            // Set up the button if conditions are met
            this.updateButton();
            // Listen for real-time status changes
            this.setupStatusListener();
        });
    }
    
    updateButton() {
        const shouldShow = this.isInApp();
        const isSubscribed = this.isPushEnabled();
        
        if (shouldShow) {
            if (!this.button) {
                // Create button if it doesn't exist
                this.createButton();
            }
            
            // Update button text based on subscription status
            if (isSubscribed) {
                this.button.textContent = '✅ Notifications Enabled';
                this.button.disabled = true;
            } else {
                this.button.textContent = '🔔 Enable Notifications';
                this.button.disabled = false;
            }
        } else {
            // Hide button if not in app
            this.hideButton();
        }
    }
    
    createButton() {
        // Create the button element
        this.button = document.createElement('button');
        this.button.style.cssText = `
            padding: 12px 24px;
            background-color: #007AFF;
            color: white;
            border: none;
            border-radius: 8px;
            font-size: 16px;
            cursor: pointer;
            margin: 10px;
        `;
        
        // Handle button clicks
        this.button.onclick = () => this.handleClick();
        
        // Add button to page (you can change this to any container)
        document.body.appendChild(this.button);
    }
    
    handleClick() {
        // Only trigger if user is in app and not subscribed
        if (this.isInApp() && !this.isPushEnabled()) {
            // This will show native prompt or settings redirect automatically
            nativeFunctions.triggerPushPrompt();
        }
    }
    
    isInApp() {
        // Check if user is in MobiLoud app
        return navigator.userAgent.toLowerCase().includes('canvas');
    }
    
    isPushEnabled() {
        // Check current subscription status
        try {
            return !!(window.mobiloudAppInfo && 
                     window.mobiloudAppInfo.pushSubscribed);
        } catch (e) {
            return false;
        }
    }
    
    setupStatusListener() {
        // Store any existing callback
        const original = window.mlPushStatusChanged;
        
        // Override with our handler
        window.mlPushStatusChanged = (isSubscribed) => {
            // Call original callback if it existed
            if (typeof original === 'function') original(isSubscribed);
            
            // Update button based on new status
            this.updateButton();
        };
    }
    
    hideButton() {
        // Remove button if it exists
        if (this.button) {
            this.button.remove();
            this.button = null;
        }
    }
    
    waitForNativeFunctions(callback, maxAttempts = 50) {
        let attempts = 0;
        
        function check() {
            attempts++;
            
            // Check if both APIs are available
            if (typeof nativeFunctions !== 'undefined' && window.mobiloudAppInfo) {
                callback(); // Ready to go!
            } else if (attempts < maxAttempts) {
                setTimeout(check, 100); // Try again in 100ms
            }
            // Stop after 5 seconds total
        }
        
        check();
    }
}

// Initialize the notification button
new PushNotificationButton();

Button Behavior Summary

The button will automatically:

  • Show when user is in the app
  • Hide when user is in a regular browser
  • Display "🔔 Enable Notifications" when push notifications are disabled
  • Display "✅ Notifications Enabled" when push notifications are enabled
  • Become disabled when notifications are already enabled
  • Update in real-time when subscription status changes
  • Handle clicks by triggering the push prompt or settings redirect