Ionic AI-Assisted Integration

Operating instructions for an AI coding agent integrating the Ionic SDK

Purpose

This runbook helps an AI coding agent integrate the Reteno Ionic SDK into an existing Ionic application and validate that the integration works correctly.

The agent must not stop after applying code changes. The integration is complete only when the required validation checks pass or a blocker is clearly documented.

Agent Role

You are an AI coding agent responsible for integrating the Reteno Ionic SDK into an existing Ionic application.

Your goal is not only to update the code, but also to validate that the SDK integration works correctly across the Ionic application layer and the required native iOS / Android platform configuration.

Do not treat this as a plain Cordova, Capacitor, native iOS, native Android, React Native, Flutter, Expo, or Unity integration by default.

Start with the Ionic project structure, Ionic framework type, and runtime type.

Apply Cordova-specific, Capacitor-specific, native iOS, or native Android steps only when the detected Ionic runtime and official Reteno Ionic setup require them.

Quick Start Prompt

Use this Ionic runbook as your operating instruction.

Integrate the Reteno Ionic SDK from scratch into the selected Ionic application.

First inspect the project and detect the Ionic project structure, Ionic framework type, runtime type, package manager, installed platforms, installed plugins, app entry point, existing Reteno usage, Firebase setup, FCM/APNs setup, native iOS/Android folders, and existing push notification logic.

Use the official Reteno Ionic SDK as the primary source of truth for Ionic SDK overview and base setup.

Use the official Ionic Android SDK Setup when Android validation is included.

Use the official Ionic iOS SDK Setup when iOS validation is included.

Use the official Ionic Push Handling when push registration, push opening, custom push data, action buttons, or deeplink validation is part of the current integration task.

Use the official Ionic User Information when user identification or externalCustomerId validation is part of the current integration task.

Use Reteno llms.txt to locate additional Ionic feature-specific documentation when needed.

Before applying Ionic SDK changes, explicitly verify the Ionic-specific critical setup decisions:

  • selected cordova-plugin-reteno version;
  • selected awesome-cordova-plugins-reteno version;
  • selected @awesome-cordova-plugins/core version;
  • whether the Reteno wrapper major matches the installed @awesome-cordova-plugins/core major;
  • for Ionic Angular, whether the Reteno wrapper is imported from awesome-cordova-plugins-reteno/ngx;
  • for Ionic Angular, whether the Reteno wrapper is registered in Angular providers:
    • AppModule providers for NgModule-based apps;
    • bootstrapApplication(...) providers for standalone Angular apps;
  • whether the project imports the Reteno wrapper from the package root by mistake;
  • whether Ionic React / Ionic Vue is actually supported by the selected Reteno Ionic setup or must be treated as a framework-specific verification path;
  • Ionic framework type:
    • Angular;
    • React;
    • Vue;
    • unknown;
  • Ionic runtime type:
    • Ionic with Cordova runtime;
    • Ionic with Capacitor runtime;
    • Ionic with both Cordova and Capacitor indicators;
    • pure Cordova app;
    • non-Ionic app;
  • whether this Ionic runbook, Cordova runbook, or Capacitor-specific path should be used;
  • Ionic CLI availability;
  • installed Cordova platforms, if Cordova runtime is used:
    • Android;
    • iOS;
    • both;
  • installed Capacitor platforms, if Capacitor runtime is used:
    • Android;
    • iOS;
    • both;
  • whether native platforms/, android/, or ios/ folders are committed or generated;
  • whether running ionic cordova prepare is allowed;
  • whether running ionic cordova platform rm/add is allowed;
  • whether running npx cap sync is allowed;
  • whether running npx cap copy is allowed;
  • whether native folders may be regenerated;
  • whether SDK_ACCESS_KEY is configured through plugin variable, config.xml, capacitor.config.ts, or runtime init(...);
  • whether this.reteno.init(...) is required and where it should be called;
  • whether Ionic Platform.ready() is used before Reteno initialization;
  • whether this.reteno.requestNotificationPermission() is required;
  • Android cordova-android >= 12.0.0, if Cordova Android is used;
  • Android FCM setup and google-services.json;
  • Android 13+ notification permission handling;
  • whether cordova-plugin-firebasex, @capacitor-firebase/messaging, expo-notifications, or other push handlers are installed and may conflict with Reteno push handling;
  • iOS deployment target is 15.0 or higher;
  • iOS IOS_DEVICE_TOKEN_HANDLING_MODE: manual or automatic;
  • whether iOS push uses direct APNs or Firebase / FCM;
  • whether this.reteno.setDeviceToken(token) is required;
  • iOS Notification Service Extension;
  • iOS Notification Content Extension, if rich push carousel is required;
  • iOS App Group exact name;
  • iOS extension native dependency setup through the active dependency manager:
    • CocoaPods;
    • Swift Package Manager;
    • mixed, when already used by the project;
  • whether the iOS extension target Reteno pod version is pinned and matches the <pod name="Reteno" spec="..."> value in the installed cordova-plugin-reteno/plugin.xml;
  • whether push handling uses the actual Reteno Ionic API methods for initial notification, foreground push, notification click, action buttons, and notification actions;
  • whether App Inbox validation is requested; do not use READ as a push status.
  • selected test environment.

Do not treat Ionic as Cordova or Capacitor before detecting the runtime type.

Do not use Ionic browser preview, ionic serve, or PWA runtime as evidence for native Reteno push validation.

Do not regenerate Cordova or Capacitor native projects unless the developer explicitly confirms that this is allowed.

Do not mark integration as complete until these decisions are confirmed or documented as not applicable.

Before making code changes, complete the Developer Preparation Checklist. If any required preparation item is missing, document it before continuing and do not mark the integration as complete until the missing validation step is completed or clearly reported as blocked.

Do not ask for all inputs upfront. Ask only for information that cannot be detected from the codebase, Reteno MCP, official Reteno documentation, or Ionic project configuration.

Preserve existing application logic. Do not overwrite Ionic app startup, Angular/React/Vue bootstrap, Platform.ready() handlers, Cordova plugins, Capacitor plugins, Firebase configuration, push notification handlers, deeplink handling, authentication flow, analytics logic, or existing native platform configuration.

Use the existing Ionic project setup. Do not switch package managers, Ionic framework, runtime, native platform ownership, Firebase setup, push provider, or SDK versions unless the developer explicitly confirms this.

Before making code changes, check the current Git branch. For evaluation, test, or temporary integration runs, create and switch to a temporary local branch unless the developer explicitly confirms another branch. Do not make temporary integration changes directly on main or master.

If a Reteno SDK access key is provided, use it through the approved project configuration method. Do not leave SDK key placeholders in the final code.

Do not hardcode secrets, Firebase server credentials, APNs credentials, service account data, private keys, certificates, or other sensitive values in committed files.

Use the selected test environment confirmed by the developer. This can be an Android emulator, physical Android device, iOS simulator, physical iOS device, local Ionic Cordova build, local Ionic Capacitor build, CI build, or another supported test environment.

After applying SDK changes, attempt to build and run the application.

If build/run fails, do not repeat the same failed action without a new hypothesis.

Continue safe diagnostics while distinct testable causes remain.

Escalate when the issue requires local environment access, external access, credentials, signing, dashboard changes, GUI interaction, local automation, Apple Developer account access, Firebase server configuration, Cordova platform regeneration, Capacitor sync, or manual device actions.

When escalation is required, ask the developer to run the app through Ionic CLI, Cordova CLI, Capacitor CLI, Android Studio, Xcode, Gradle, CocoaPods, or the relevant project tool and provide:

  • the exact build or runtime error;
  • crash reason, if available;
  • relevant logs;
  • device, simulator, or emulator details;
  • Ionic runtime details;
  • Cordova or Capacitor platform details;
  • reproduction steps.

Do not stop after code changes.

Before MCP-based validation, verify that Reteno MCP is connected in the same environment where you are running.

After the app builds and runs, validate the integration through Reteno MCP:

  • find the contact;
  • verify mobilePushToken;
  • identify token type: FCM or APNs;
  • send a test push, when the capability is available and approved;
  • verify DELIVERED;
  • verify CLICKED after the push notification is opened.

Validate every Reteno SDK feature that you integrate, modify, or are explicitly asked to verify.

At minimum, for mobile push integration, validate contact creation, mobilePushToken, token type, test push, DELIVERED, and CLICKED.

Run feature-specific validation when the current integration task includes additional SDK features such as In-App messages, custom events, deeplinks, custom push data, screen tracking, app lifecycle events, or externalCustomerId.

If a step cannot be completed programmatically, ask for the required manual action and continue after confirmation.

If an MCP capability is unavailable, document it as a missing MCP capability and continue with the remaining validation steps where possible.

Return the final report using the format defined in this runbook.

Do not mark the integration as complete until the required validation checks pass or a blocker is clearly documented.

Source of Truth

Use only official Reteno sources, official Ionic / Cordova / Capacitor documentation, and the current customer application codebase for Ionic SDK integration.

Do not duplicate the full Reteno documentation catalogue in this runbook. Use llms.txt to locate additional feature-specific documentation when needed.

SourceHow to access itUse it forIf unavailable
Customer application codebaseInspect the current repository or workspace opened in the AI coding agentDetect Ionic project structure, framework type, runtime type, package manager, installed platforms, installed plugins, ionic.config.json, package.json, config.xml, capacitor.config.*, www/, src/, platforms/, android/, ios/, Firebase/APNs setup, push handlers, deeplinks, and files to modifyAsk the user to open the project in the AI coding agent or provide the required project files
Reteno Ionic SDKOpen Ionic SDKUse it as the primary source of truth for Ionic SDK overview, supported stack, plugin/wrapper setup, initialization, wrapper version compatibility, and exported TypeScript typesAsk the developer to confirm Ionic setup requirements
Reteno Ionic Android SDK SetupOpen Ionic Android SDK SetupApply Android-specific Ionic setup: plugin installation, wrapper installation, cordova-android, config.xml, Firebase / FCM setup, Android 13+ notification permission, Firebasex warning, custom FCM service, Capacitor Android setup, and deeplinksAsk the developer to confirm Android Ionic setup requirements
Reteno Ionic iOS SDK SetupOpen Ionic iOS SDK SetupApply iOS-specific Ionic setup: iOS deployment target, plugin/wrapper installation, config.xml, Notification Service Extension, Notification Content Extension, App Groups, extension Podfile, token handling mode, Firebase / FCM path, permission request, setDeviceToken, Capacitor iOS setup, and rich push setupAsk the developer to confirm iOS Ionic setup requirements
Reteno Ionic Push HandlingOpen Ionic Push HandlingConfigure or verify push registration, foreground push handling, notification opening, token refresh handling, notification channels, custom push data, and deeplinksAsk the developer to confirm Ionic push handling requirements
Reteno Ionic User InformationOpen Ionic User InformationConfigure or verify user identification, externalUserId, user attributes, anonymous user attributes, multi-account attributes, languageCode, timeZone, and marketId supportAsk the developer to confirm user identification requirements
Reteno MCP Server ReferenceOpen Reteno MCP Server and verify whether Reteno MCP is connected in the AI agent environmentDiscover available and authorized Reteno MCP capabilities; validate Reteno-side data when the required capability is available: contact lookup, mobilePushToken verification, token type validation, test push creation/sending, DELIVERED / CLICKED status checks, event verification, and feature-specific validationAsk the developer to connect Reteno MCP when MCP-based validation is required. If MCP is unavailable or a required capability cannot provide reliable evidence, use an approved Reteno UI, backend, SDK-log, device-log, redacted network-log, screenshot, or developer / QA fallback when available. Report the validation as blocked only when the required result cannot be verified through MCP or any approved fallback evidence.
Reteno llms.txtOpen Reteno llms.txtLocate the latest Reteno documentation pages, SDK guides, API references, release notes, and feature-specific documentationUse direct documentation links or ask the user to provide the relevant Reteno documentation page
Mobile push error codesOpen Mobile push error codesTroubleshoot failed test push validation, especially when push status ERROR is presentAsk the user or Support team to provide the relevant error code explanation
Ionic documentationOpen Ionic DocumentationVerify Ionic project structure, Angular/React/Vue framework setup, Ionic CLI behavior, Cordova/Capacitor integration, and build/run commandsAsk the developer to confirm Ionic project structure and runtime
Cordova documentationOpen Apache Cordova DocumentationVerify Cordova project structure, platform commands, plugin lifecycle, config.xml, platform folders, and build behavior when Ionic Cordova runtime is usedAsk the developer to confirm Cordova workflow and build setup
Capacitor documentationOpen Capacitor DocumentationVerify Capacitor sync/copy behavior, capacitor.config.*, native project ownership, and plugin compatibility when Ionic Capacitor runtime is usedAsk the developer to confirm Capacitor workflow and build setup

Note — Reteno MCP: Reteno MCP must be connected in the same environment where the AI coding agent runs. Before using MCP for validation, discover which capabilities are available and authorized. Do not assume support for sending pushes, retrieving DELIVERED / CLICKED statuses, or managing In-App messages until capability discovery is completed.

Note — Ionic runtime: Ionic is not enough to determine the integration path. Detect whether the app uses Cordova runtime, Capacitor runtime, both, or neither before making SDK changes.

Note — Capacitor compatibility: Capacitor can use Cordova plugins through a compatibility layer, but Cordova plugin hooks do not run the same way. Do not assume Cordova automatic setup is applied in Capacitor projects.

Note — browser preview: Ionic browser preview, ionic serve, or PWA runtime is not valid evidence for native Reteno mobile push validation. Use a native Android/iOS build.

Agent Behaviour Rules

Follow these rules throughout the Ionic SDK integration:

  • Inspect the project before making any code changes.
  • Detect the Ionic project structure, Ionic framework type, runtime type, package manager, installed platforms, installed plugins, app entry point, native iOS/Android folders, Firebase setup, push notification setup, config files, and notification handlers from project files whenever possible.
  • Ask the user only for information that cannot be detected from the project, Reteno MCP, official Reteno documentation, or Ionic project configuration.
  • Use the existing Ionic project setup. Do not switch package managers, Ionic framework, runtime, app architecture, Firebase setup, push provider, native project ownership, or SDK versions unless the developer explicitly confirms this.
  • Treat Ionic as the highest-level framework. Do not start with Cordova, Capacitor, React Native, Flutter, Expo, native iOS, or native Android setup unless project detection confirms that Ionic is not the correct runbook.
  • Preserve existing application logic.
  • Do not overwrite Ionic app startup, Angular/React/Vue bootstrap, Platform.ready() handlers, Cordova plugins, Capacitor plugins, Firebase configuration, push notification handlers, deeplink handling, authentication flow, analytics logic, or existing native platform configuration.
  • Treat the Reteno SDK_ACCESS_KEY as client-side SDK configuration and follow the project's approved repository and configuration policy for it. Do not unnecessarily expose the full SDK access key in prompts, logs, screenshots, terminal output, tool output, or final reports. Treat Firebase Admin credentials, APNs private keys, certificates, signing credentials, Reteno REST API credentials, service-account data, and other server-side credentials as hard secrets and never expose or commit them.
  • If the repository contains local agent instructions, such as CLAUDE.md, Cursor rules, or similar files, inspect them before making changes. If they conflict with this runbook, ask the developer to confirm which instruction has priority.
  • If a step cannot be completed programmatically, ask the developer to complete it manually.
  • After applying code changes, continue validation.
  • Use Reteno MCP for validation only after discovering that the required capability is available and authorized in the current environment.
  • Do not report the integration as complete until all required validation checks pass or a blocker is clearly documented.
  • Validate every Reteno SDK feature that is integrated, modified, or explicitly requested.
  • If validation fails, identify the failed step, troubleshoot, retry safe fixes, and document unresolved blockers in the final report.
  • Apply automatic fixes only when they are limited to TypeScript code, Ionic configuration, Cordova configuration, Capacitor configuration, plugin setup, dependency setup, native project configuration generated or owned by the current Ionic runtime, or available and authorized MCP capabilities.
  • Do not remove and re-add Cordova platforms unless the developer explicitly confirms this.
  • Do not run ionic cordova prepare, ionic cordova platform rm, ionic cordova platform add, cordova prepare, cordova clean, npx cap sync, npx cap copy, or regenerate native platform projects without confirming that this is safe for the project.
  • Do not change external app configuration, credentials, APNs/FCM setup, sandbox/production settings, Firebase project settings, Apple Developer account settings, signing, provisioning, or Reteno dashboard settings without explicit developer or admin confirmation.

Ionic Project Detection

Use this runbook for Ionic applications.

Do not select this Ionic runbook merely because a project contains a WebView or native iOS/Android folders.

First determine the actual project type and Ionic runtime.

Use the Ionic SDK flow when the project contains Ionic-specific files or configuration, such as:

  • ionic.config.json;
  • Ionic dependencies in package.json;
  • @ionic/angular;
  • @ionic/react;
  • @ionic/vue;
  • @ionic/core;
  • Ionic CLI scripts;
  • src/app/;
  • src/main.ts;
  • src/App.tsx;
  • src/main.tsx;
  • src/router/;
  • src/theme/;
  • config.xml;
  • Cordova plugins;
  • capacitor.config.ts;
  • capacitor.config.json;
  • android/;
  • ios/;
  • platforms/;
  • plugins/;
  • www/;
  • cordova-plugin-reteno;
  • awesome-cordova-plugins-reteno.

Before making changes, detect:

  • Ionic project structure;
  • Ionic framework type:
    • Angular;
    • React;
    • Vue;
    • unknown;
  • Ionic runtime type:
    • Cordova;
    • Capacitor;
    • both Cordova and Capacitor indicators;
    • browser/PWA only;
    • unknown;
  • package manager: npm, Yarn, pnpm, or another package manager;
  • Ionic CLI version, if available;
  • Angular/React/Vue version, if relevant;
  • @awesome-cordova-plugins/core version, if installed;
  • awesome-cordova-plugins-reteno version, if installed;
  • cordova-plugin-reteno version, if installed;
  • installed Cordova platforms, if Cordova runtime is used;
  • installed Capacitor platforms, if Capacitor runtime is used;
  • config.xml;
  • capacitor.config.ts;
  • capacitor.config.json;
  • app entry point;
  • Platform.ready() usage;
  • existing Reteno initialization, if any;
  • native platforms/android, platforms/ios, android/, and ios/ folders;
  • whether native folders are committed or generated;
  • Firebase / FCM setup;
  • google-services.json;
  • GoogleService-Info.plist;
  • Android package name / applicationId;
  • iOS bundle ID;
  • existing push notification setup;
  • existing push notification plugins;
  • cordova-plugin-firebasex, if installed;
  • @capacitor-firebase/messaging, if installed;
  • @capacitor/push-notifications, if installed;
  • legacy Cordova FCM or push-notification plugins, if installed;
  • existing deeplink plugin or routing layer;
  • existing custom event tracking;
  • existing authentication or user identification flow;
  • existing In-App message setup, if any.

Ionic project classification

Classify the project as one of the following:

  1. Ionic app with Cordova runtime

    The project has Ionic configuration and uses Cordova platforms/plugins.

    Use this Ionic runbook.

    Apply Cordova-specific setup only through the Ionic Cordova workflow.

  2. Ionic app with Capacitor runtime

    The project has Ionic configuration and uses Capacitor native projects.

    Use this Ionic runbook with the Capacitor-specific path.

    Do not assume Cordova plugin hooks run.

  3. Ionic app with both Cordova and Capacitor indicators

    The project contains both Cordova and Capacitor configuration.

    Stop before making changes and ask the developer to confirm the active runtime.

    Do not install or sync plugins until the active runtime is confirmed.

  4. Pure Cordova app

    The project has Cordova configuration but no Ionic application layer.

    Stop and use the Cordova runbook instead.

  5. Browser/PWA-only Ionic app

    The app does not have a native Cordova or Capacitor runtime.

    Do not attempt Reteno native mobile push validation.

    Report native SDK validation as blocked until a native runtime is provided.

  6. Non-Ionic project

    If the project is React Native, Flutter, Expo, native iOS, native Android, Unity, or another framework, stop and use the corresponding runbook.

Ionic runtime ownership

Before editing anything under native folders, determine whether they are generated artifacts or committed source.

For Ionic Cordova:

  • inspect platforms/;
  • inspect config.xml;
  • inspect Cordova plugins;
  • prefer changes through Ionic/Cordova plugin configuration;
  • run ionic cordova prepare only when approved.

For Ionic Capacitor:

  • inspect android/;
  • inspect ios/;
  • inspect capacitor.config.*;
  • prefer changes through Capacitor config and plugin sync;
  • run npx cap sync only when approved.

Native regeneration approval policy

Running these commands may rewrite native platform files:

ionic cordova prepare
ionic cordova platform rm android
ionic cordova platform add android
ionic cordova platform rm ios
ionic cordova platform add ios
cordova prepare
cordova clean
npx cap sync
npx cap copy

Do not run them without explicit developer approval.

Before running any native regeneration, prepare, sync, or copy command, document:

  • why it is required;
  • which runtime it affects:
    • Ionic Cordova;
    • Ionic Capacitor;
  • which platform it affects:
    • Android;
    • iOS;
    • both;
  • whether native folders are committed;
  • whether manual native changes may be overwritten;
  • whether the developer approves the action.

If native regeneration is not approved, continue only with non-blocked setup and report native configuration / runtime validation as blocked or pending.

Change-safety boundaries

Follow these change-safety rules throughout the Ionic integration.

Ionic workflow preservation

Preserve the existing Ionic workflow.

Do not convert:

  • Ionic Cordova to Ionic Capacitor;
  • Ionic Capacitor to Ionic Cordova;
  • Ionic Angular to Ionic React or Vue;
  • Ionic React to Ionic Angular or Vue;
  • Ionic Vue to Ionic Angular or React;
  • Ionic to pure Cordova;
  • Ionic to native Android or native iOS;
  • npm to Yarn or pnpm;
  • Yarn to npm or pnpm;
  • pnpm to npm or Yarn.

Do not generate, delete, or regenerate native folders without explicit developer approval.

Ionic startup preservation

Before editing TypeScript source files, inspect:

  • Ionic app bootstrap;
  • Angular AppModule, if Ionic Angular is used;
  • Angular services/providers, if Ionic Angular is used;
  • React root component, if Ionic React is used;
  • Vue app entry point, if Ionic Vue is used;
  • Platform.ready() usage;
  • router initialization;
  • push plugin initialization;
  • Firebase plugin initialization;
  • authentication initialization;
  • analytics initialization;
  • deeplink initialization;
  • existing Reteno initialization, if present.

Do not initialize Reteno before the Ionic native platform is ready.

Do not duplicate this.reteno.init(...).

Do not move unrelated app startup logic unless the developer confirms this.

Application startup blocker and Reteno causality isolation

Do not classify an application startup failure as a Reteno integration failure only because the failure appears during the Reteno integration run.

If the Ionic application:

  • does not render the application root;
  • remains on a splash screen or white screen;
  • does not complete Angular / React / Vue bootstrap;
  • does not reach Platform.ready();
  • hangs in an application initializer;
  • fails before the Reteno initialization path can be exercised;

first determine whether the failure is caused by Reteno or by pre-existing application startup logic.

Inspect the actual startup chain.

For Ionic Angular, this may include:

  • Angular APP_INITIALIZER;
  • AppModule;
  • service factories;
  • native plugin initialization;
  • database initialization;
  • authentication bootstrap;
  • application configuration loading;
  • other asynchronous startup dependencies.

For Ionic React or Ionic Vue, inspect the equivalent application bootstrap and asynchronous startup chain.

Keep these results separate:

Native Reteno integration / build
Application bootstrap
Reteno runtime initialization
Core push validation

Do not treat a successful native Reteno build as proof that Reteno runtime initialization or mobile push validation passed.

When safe and developer-approved, use a controlled causality isolation test.

A suitable A/B test may temporarily disable only the Reteno application-level bootstrap or initialization call while preserving the rest of the application startup path.

Before the isolation test:

  • preserve the original code;
  • keep the temporary change local and reversible;
  • do not remove native Reteno configuration;
  • do not modify unrelated startup logic;
  • obtain developer approval when the temporary change affects application behavior.

Compare:

A — application startup with Reteno bootstrap enabled
B — application startup with Reteno bootstrap disabled

If the same startup failure occurs in both A and B:

  • classify the failure as pre-existing or non-Reteno unless other evidence proves otherwise;
  • do not report it as a Reteno SDK defect;
  • restore the original Reteno bootstrap code;
  • document the actual startup blocker;
  • continue Reteno runtime validation only when the application can reach the required runtime state.

If disabling Reteno changes the failure behavior:

  • investigate the Reteno initialization path;
  • inspect the exact runtime error;
  • do not conclude causality until the changed behavior is understood.

Do not use native build success as evidence that:

  • notification permission was requested;
  • a push token was registered;
  • mobilePushToken was assigned;
  • DELIVERED passed;
  • CLICKED passed.

If a pre-existing application startup issue prevents Reteno runtime validation, report the affected validation step as:

Blocked by pre-existing application startup failure

rather than:

Reteno integration failed

Document:

  • whether the application completed normal startup;
  • where startup stopped;
  • whether Reteno runtime initialization was reached;
  • whether a Reteno-enabled / Reteno-disabled isolation test was performed;
  • whether the failure reproduced without Reteno bootstrap;
  • final blocker classification.

Wrapper and dependency preservation

Before installing the Reteno Ionic wrapper, inspect:

  • package.json;
  • package manager;
  • lockfile;
  • @awesome-cordova-plugins/core version;
  • existing awesome-cordova-plugins-* packages;
  • Angular/React/Vue framework version;
  • existing Ionic Native / Awesome Cordova Plugins usage.

Install awesome-cordova-plugins-reteno major version that matches the installed @awesome-cordova-plugins/core major.

Do not upgrade @awesome-cordova-plugins/core across major versions unless the developer explicitly approves this.

Do not switch package managers.

Do not generate another package manager's lockfile.

Wrapper peer-dependency compatibility

Do not validate the Reteno Ionic wrapper only by comparing:

awesome-cordova-plugins-reteno major

with:

@awesome-cordova-plugins/core major

Before installing or approving the selected wrapper version, inspect the peer dependencies declared by that exact wrapper version.

Depending on the selected package version, relevant peer dependencies may include:

  • @awesome-cordova-plugins/core;
  • rxjs;
  • Angular packages;
  • other package peers declared by the selected wrapper release.

Use the peer dependencies declared by the actual selected package version as the source of truth.

Compare them with the versions already installed in the application.

If a peer dependency does not match:

  • do not automatically upgrade Angular;
  • do not automatically upgrade RxJS;
  • do not automatically downgrade the Reteno wrapper;
  • do not automatically change @awesome-cordova-plugins/core;
  • do not silently bypass package-manager peer-dependency validation.

If installation requires a compatibility override such as:

--legacy-peer-deps

treat it as an explicit workaround, not as the default installation path.

Before using such a workaround:

  1. document the exact peer-dependency mismatch;
  2. determine whether another officially supported wrapper version resolves it;
  3. check whether the mismatch affects APIs used by the current application;
  4. ask the developer to approve the workaround;
  5. preserve existing framework dependencies unless an approved version change is required.

After installation with a peer-dependency workaround:

  • verify the wrapper import;
  • verify Angular dependency injection when Ionic Angular is used;
  • verify the application build;
  • verify Reteno runtime initialization;
  • run the required Reteno validation;
  • document the remaining compatibility risk.

A successful package installation with ignored peer-dependency checks does not prove full wrapper compatibility.

Do not permanently describe a specific RxJS, Angular, or wrapper version combination as incompatible unless the selected package metadata or official documentation establishes that requirement.

Dependency patch and vendored-wrapper preservation

Do not leave required integration fixes as untracked manual edits inside:

node_modules/

or another package manager's temporary dependency installation directory.

If a third-party dependency or Reteno wrapper package must be patched to complete the integration:

  1. verify that the issue reproduces with the selected package version;
  2. verify whether an official fixed release already exists;
  3. ask the developer to approve the workaround;
  4. use the project's existing reproducible patch mechanism when possible.

Approved mechanisms may include:

  • package-manager-supported patching;
  • patch-package, when already used or approved by the project;
  • an idempotent postinstall script;
  • a reviewed vendored build artifact;
  • another repository-approved dependency workaround.

Do not switch package managers only to obtain a different patch mechanism.

If the wrapper must be built locally because the published package is incomplete:

  • build it from the official package source or approved upstream repository;
  • document the exact source/version;
  • store the workaround in a reproducible project location;
  • document how the application imports it;
  • do not silently treat a locally built wrapper as equivalent to the published package.

After implementing a dependency workaround:

  • reinstall dependencies in a clean-enough test when practical;
  • verify that the workaround is reapplied;
  • rebuild the application;
  • verify that the original issue remains fixed.

Treat local package patches, vendored wrapper builds, and postinstall modifications as temporary unless the developer explicitly accepts them as maintained project behavior.

If an upstream fixed release becomes available:

  • recommend upgrading to the fixed version;
  • remove the workaround after the upgrade is validated.

Document in the final report:

  • affected package;
  • affected version;
  • defect or incompatibility;
  • workaround type;
  • patch/vendor/script location;
  • whether reinstall preserves the fix;
  • upstream fix status;
  • workaround removal condition.

Collateral legacy-plugin and platform compatibility failures

A Reteno integration may require a newer Cordova / Capacitor platform, Android build toolchain, iOS deployment target, CocoaPods resolution, Firebase dependency, or another supported native environment.

Those changes may expose defects in legacy application plugins that were already incompatible with the newer platform or toolchain.

Do not automatically classify those failures as Reteno SDK defects.

For every compatibility issue discovered during the integration, classify it as one of:

Reteno SDK defect
Reteno native dependency requirement
Cordova / Capacitor framework requirement
Android / iOS toolchain compatibility issue
Pre-existing legacy-plugin defect
Collateral incompatibility exposed by an upgrade
Unrelated application issue

Possible collateral compatibility failures may include:

  • removed Firebase APIs;
  • deprecated Android Firebase APIs;
  • removed Swift APIs;
  • outdated CocoaPods dependency pins;
  • obsolete native header imports;
  • module or header visibility conflicts;
  • Gradle syntax incompatible with the selected Android toolchain;
  • existing startup code that fails under the selected Cordova / Capacitor platform.

Treat these as examples, not as universal Reteno errors.

Do not hardcode project-specific compiler errors or removed APIs into the standard Reteno integration flow.

Before patching an unrelated dependency:

  1. identify the failing package and version;
  2. capture the first actionable build or runtime error;
  3. determine why the problem became visible during the current integration;
  4. check whether a compatible upstream package version already exists;
  5. obtain developer approval before changing, replacing, or patching the dependency;
  6. use the project's approved reproducible patch mechanism;
  7. rebuild and verify the affected application behavior.

When patch-package or another dependency patch mechanism is used:

  • keep the patch minimal;
  • document the exact affected package;
  • document why the change is required;
  • verify that dependency reinstall reapplies the patch;
  • identify the condition for removing the patch.

If multiple legacy application plugins require compatibility changes, recommend separate compatibility or maintenance follow-up.

Do not mix large unrelated plugin migrations into the Reteno integration unless they are required to make the selected validation environment runnable and the developer approves them.

Document separately:

  • Reteno integration changes;
  • Reteno-required platform or toolchain changes;
  • pre-existing fixes;
  • collateral legacy-plugin fixes;
  • application functionality that requires additional regression testing.

Ionic Angular wrapper import and provider registration

For Ionic Angular, always import the Reteno service from the Angular /ngx entry point:

import { AwesomeCordovaPluginReteno } from 'awesome-cordova-plugins-reteno/ngx';

Do not import the service from the package root:

import { AwesomeCordovaPluginReteno } from 'awesome-cordova-plugins-reteno';

The package root entry point is a legacy AngularJS bridge and does not provide Angular dependency-injection metadata for Ionic Angular.

Only awesome-cordova-plugins-reteno/ngx exposes the Angular service.

The /ngx service must still be registered explicitly in Angular providers.

Do not assume it is globally provided.

NgModule-based Ionic Angular

Register the wrapper in the app module or another approved Angular module:

import { NgModule } from '@angular/core';
import { AwesomeCordovaPluginReteno } from 'awesome-cordova-plugins-reteno/ngx';

@NgModule({
  providers: [AwesomeCordovaPluginReteno]
})
export class AppModule {}

Standalone Angular

Register the wrapper in the standalone bootstrap providers:

import { bootstrapApplication } from '@angular/platform-browser';
import { AwesomeCordovaPluginReteno } from 'awesome-cordova-plugins-reteno/ngx';

bootstrapApplication(AppComponent, {
  providers: [AwesomeCordovaPluginReteno]
});

Expected result:

  • Angular dependency injection can resolve AwesomeCordovaPluginReteno;
  • constructor injection does not throw NullInjectorError;
  • Reteno initialization can use the injected wrapper service;
  • the final report confirms that the wrapper was registered in Angular providers.

If the project uses Ionic React or Ionic Vue, do not apply Angular dependency-injection guidance.

Cordova runtime preservation

If Ionic Cordova runtime is used, inspect:

  • config.xml;
  • platforms/;
  • plugins/;
  • Cordova plugin variables;
  • Cordova hooks;
  • ionic cordova scripts;
  • existing Cordova push plugins;
  • existing Cordova Firebase plugins.

Do not remove and re-add Cordova platforms without explicit developer approval.

Do not run Cordova platform commands until platform ownership is clear.

Capacitor runtime preservation

If Ionic Capacitor runtime is used, inspect:

  • capacitor.config.ts;
  • capacitor.config.json;
  • android/;
  • ios/;
  • npx cap sync history, if available;
  • existing Capacitor plugins;
  • existing Cordova-compatible plugins;
  • existing Firebase/Messaging setup.

Do not assume Cordova plugin hooks run.

Do not manually edit generated native files before confirming whether the project owns them as source.

Do not run npx cap sync or npx cap copy without explicit developer approval.

Native platform preservation

If native platform folders exist, inspect them before making changes.

Inventory:

  • Android Gradle files;
  • AndroidManifest;
  • Firebase setup;
  • existing Firebase Messaging service;
  • iOS Podfile;
  • iOS project/workspace;
  • iOS entitlements;
  • Notification Service Extension;
  • Notification Content Extension;
  • App Groups;
  • existing notification delegates;
  • existing Firebase/APNs setup;
  • existing deeplink configuration.

Do not remove or replace existing native handlers unless the official Ionic Reteno setup and developer confirmation require it.

SDK demo app exclusion

Do not use the SDK repository's example application as integration evidence.

Do not copy its Firebase files, identifiers, access keys, signing configuration, provisioning, APNs credentials, or Reteno app configuration.

Run integration validation only in the target application or an approved private test fork.

Use separate non-production application IDs, Firebase projects, Reteno environments, and signing configuration for validation.

Sandbox Firebase / package identity validation path

The agent may use a sandbox Firebase / Reteno app configuration only when the developer explicitly approves this as a dry-run validation path.

If the agent changes package identity, bundle ID, Firebase client configuration, or Reteno app to match a demo, sample, or preconfigured sandbox setup:

  • document that this is a sandbox-only validation path;
  • do not report the branch as merge-ready or production-ready;
  • document the original package name / bundle ID;
  • document the temporary sandbox package name / bundle ID;
  • document which Firebase project and Reteno mobile app were used;
  • document any app behavior that may break because of the package identity change;
  • do not treat unrelated product behavior broken by the package identity change as a Reteno SDK defect;
  • require repeated validation before production use with the real package name / bundle ID, real Firebase project, real Reteno mobile app, real access key, and real platform config.

A successful sandbox validation proves that the SDK flow can work in the selected environment.

It does not prove that the production app configuration is complete.

Retry and escalation policy

Do not repeat the same failed action without a new hypothesis.

Continue safe diagnostics while distinct testable causes remain.

Escalate when external access, credentials, signing, Apple Developer account access, Firebase server configuration, Reteno dashboard changes, GUI interaction, Cordova platform regeneration, Capacitor sync, or manual device actions are required.

Record attempted fixes and the first actionable error.

Do not retry indefinitely.

Required Inputs

Ask the developer only for information that cannot be detected from the project files, Reteno MCP, official Reteno documentation, or Ionic project configuration.

Before asking the developer, inspect the project and detect:

  • Ionic project structure;
  • package.json;
  • package manager;
  • Ionic framework type:
    • Angular;
    • React;
    • Vue;
    • unknown;
  • Ionic runtime type:
    • Cordova;
    • Capacitor;
    • both Cordova and Capacitor indicators;
    • browser/PWA only;
    • unknown;
  • Ionic CLI version, if available;
  • @awesome-cordova-plugins/core version, if installed;
  • awesome-cordova-plugins-reteno version, if installed;
  • cordova-plugin-reteno version, if installed;
  • ionic.config.json;
  • config.xml, if Cordova runtime is used;
  • capacitor.config.ts or capacitor.config.json, if Capacitor runtime is used;
  • src/ source structure;
  • app entry point;
  • Ionic Platform.ready() usage;
  • installed Cordova platforms, if Cordova runtime is used;
  • installed Capacitor platforms, if Capacitor runtime is used;
  • installed Cordova plugins;
  • installed Capacitor plugins;
  • native platforms/android, platforms/ios, android/, and ios/ folders;
  • whether native folders are committed or generated;
  • Firebase / FCM configuration;
  • google-services.json;
  • GoogleService-Info.plist;
  • Android package name / applicationId;
  • iOS bundle ID;
  • existing push notification handling;
  • existing Firebase / Firebasex plugin usage;
  • existing Capacitor Firebase Messaging usage;
  • existing deeplink handling;
  • existing custom event tracking;
  • existing user identification or login flow;
  • existing In-App setup, if present.

Required for Ionic SDK integration

Ask for these values only if they are missing, unclear, or cannot be detected automatically:

  • Reteno SDK access key or approved project configuration method for providing it;
  • Reteno app or environment name;
  • environment type:
    • development;
    • staging;
    • production;
  • target validation platform:
    • Android only;
    • iOS only;
    • both Android and iOS;
  • Ionic framework type, if it cannot be detected:
    • Angular;
    • React;
    • Vue;
  • Ionic runtime type, if it cannot be detected:
    • Ionic Cordova;
    • Ionic Capacitor;
    • both Cordova and Capacitor indicators;
    • browser/PWA only;
  • confirmation whether this Ionic runbook, Cordova runbook, or Capacitor-specific path should be used;
  • confirmation whether native folders are committed source or generated artifacts;
  • confirmation whether ionic cordova prepare is allowed;
  • confirmation whether ionic cordova platform rm/add is allowed;
  • confirmation whether npx cap sync is allowed;
  • confirmation whether npx cap copy is allowed;
  • confirmation whether plugin reinstall is allowed;
  • confirmation which Reteno mobile app should be used for each target platform;
  • confirmation whether the selected Reteno mobile app is configured for FCM or APNs;
  • confirmation of which SDK features must be enabled:
    • mobile push;
    • custom events;
    • user identification;
    • In-App messages;
    • deeplinks;
    • custom push data;
    • screen tracking;
    • app lifecycle events.

Required for Ionic Cordova setup

Ask for these values only when Ionic Cordova runtime is used and the information is missing, unclear, or cannot be detected automatically:

  • confirmation that config.xml is the active Cordova configuration file;
  • confirmation that cordova-plugin-reteno may be installed or updated;
  • confirmation that awesome-cordova-plugins-reteno may be installed or updated;
  • confirmation that the wrapper major should match the installed @awesome-cordova-plugins/core major;
  • confirmation whether Cordova platform folders are committed or generated;
  • confirmation whether ionic cordova prepare is allowed;
  • confirmation whether ionic cordova platform rm/add is allowed.

Required for Ionic Capacitor setup

Ask for these values only when Ionic Capacitor runtime is used and the information is missing, unclear, or cannot be detected automatically:

  • confirmation that capacitor.config.ts or capacitor.config.json is the active Capacitor configuration file;
  • confirmation that cordova-plugin-reteno may be installed through Capacitor compatibility;
  • confirmation that awesome-cordova-plugins-reteno may be installed or updated;
  • confirmation that npx cap sync is allowed;
  • confirmation that npx cap copy is allowed;
  • confirmation whether native android/ and ios/ folders are committed source;
  • confirmation whether manual native changes are allowed;
  • confirmation whether Cordova plugin hooks are expected to run or whether manual setup is required.

Required for Ionic Android push setup and validation

Ask for these values only when Android validation is included and the information is missing, unclear, or cannot be detected automatically:

  • confirmation that cordova-android version is 12.0.0 or higher, if Cordova Android is used;
  • confirmation that Firebase / FCM is configured for Android;
  • confirmation that google-services.json belongs to the correct Firebase project;
  • confirmation that google-services.json matches the effective Android package name / applicationId;
  • confirmation that Google Services Gradle plugin is applied;
  • confirmation whether cordova-plugin-firebasex is installed;
  • confirmation whether @capacitor-firebase/messaging is installed;
  • confirmation whether another push provider owns token or message handling;
  • confirmation whether the app has a custom FirebaseMessagingService;
  • confirmation that Android 13+ notification permission can be requested at runtime;
  • confirmation that the selected Reteno mobile app is configured with FCM token type;
  • confirmation that Reteno MCP is connected and available in the AI coding agent environment;
  • confirmation that the signed-in Reteno account has access to the selected Reteno app/environment;
  • access to the selected Android test environment:
    • Android emulator;
    • physical Android device;
    • another supported environment;
  • confirmation that push validation is supported in the selected Android test environment;
  • confirmation that the developer or QA engineer can open the delivered test push notification if the agent cannot interact with the environment directly.

Required for Ionic iOS push setup and validation

Ask for these values only when iOS validation is included and the information is missing, unclear, or cannot be detected automatically:

  • confirmation that iOS deployment target is 15.0 or higher;
  • confirmation that Xcode 15.0 or higher is available;
  • confirmation that Swift 5.7 or higher is supported by the project;
  • iOS bundle ID;
  • push route:
    • direct APNs;
    • Firebase / FCM with APNs transport;
  • selected IOS_DEVICE_TOKEN_HANDLING_MODE:
    • manual;
    • automatic;
  • confirmation whether this.reteno.setDeviceToken(token) is required;
  • confirmation that GoogleService-Info.plist belongs to the correct Firebase project, if iOS uses Firebase / FCM;
  • confirmation that Firebase has valid APNs credentials, if iOS uses Firebase / FCM;
  • confirmation that Reteno uses the corresponding Firebase project, if iOS uses Firebase / FCM;
  • confirmation that APNs sandbox / production route is correct, if direct APNs is used;
  • confirmation that Push Notifications capability can be configured;
  • confirmation that App Groups can be configured;
  • confirmation that Notification Service Extension can be created or updated;
  • confirmation that Notification Content Extension can be created or updated, if rich push UI is required;
  • confirmation that extension native dependency changes are allowed through the active iOS dependency manager;
  • confirmation that Apple signing / provisioning can be updated by the developer or admin;
  • access to the selected iOS test environment:
    • iOS simulator, if supported and confirmed by the developer;
    • physical iOS device;
    • another supported iOS test environment;
  • confirmation that push validation is supported in the selected iOS test environment;
  • confirmation that the developer or QA engineer can open the delivered test push notification if the agent cannot interact with the simulator or device directly.

Required for feature-specific custom event validation

Ask for these inputs when custom event validation is part of the current integration task:

  • confirmation that a test custom event can be added to the Ionic app code;
  • confirmed event name for validation;
  • access to Reteno MCP, Reteno UI, backend data, event log, SDK logs, device logs, or API response to verify that the event was received and assigned to the correct contact.

Do not hardcode a required event name unless the developer confirms it.

Required for feature-specific In-App validation

Ask for these inputs only when In-App validation is part of the current integration task:

  • confirmation whether an In-App message already exists or should be created for validation;
  • existing In-App message name or ID, if an existing In-App message should be used;
  • confirmation whether the default In-App message is available in the selected Reteno account;
  • confirmed trigger type:
    • app open;
    • uniquely named event;
    • mobile-push + In-App;
    • another approved trigger;
  • confirmed trigger event name, if event-triggered In-App validation is part of the current integration task;
  • access to the selected test environment where the In-App message should appear;
  • confirmation that the developer, admin, or QA engineer can create, configure, publish, open, or click the In-App message manually if MCP cannot do it.

Do not create, update, publish, configure, attach, or send In-App messages without explicit developer or admin approval.

Required for feature-specific externalCustomerId validation

Ask for these values when the current integration task includes login, registration, user identification, or explicitly asks to validate externalCustomerId.

For externalCustomerId validation, ask for:

  • confirmation that login or registration flow should be tested;
  • test login or registration credentials, if required;
  • expected stable customer ID format;
  • confirmation that the agent, developer, user, or QA engineer can complete the login or registration flow.

Do not validate externalCustomerId unless this check is part of the current integration task.

Required for deeplink or custom push data validation

Ask for these values only when deeplink or custom push data validation is part of the current integration task:

  • expected deeplink format;
  • expected Ionic route / WebView navigation behavior;
  • expected custom push payload fields;
  • expected destination screen or app behavior;
  • app-level deeplink solution:
    • custom URL scheme;
    • Universal Links;
    • Android App Links;
    • Branch.io;
    • Ionic router;
    • another routing provider;
  • whether the test should cover foreground, background, and terminated app states.

Security rules

Distinguish client-side mobile SDK configuration from hard server-side secrets.

SDK access key handling

SDK_ACCESS_KEY is client-side mobile SDK configuration.

Depending on project policy, it may be stored in:

  • config.xml;
  • capacitor.config.ts;
  • capacitor.config.json;
  • approved runtime configuration;
  • another approved project configuration method.

Whether the SDK access key is committed to the repository is governed by the project’s policy.

The Android build may embed SDK access key metadata into generated native configuration.

It is safe to verify that the SDK access key configuration name or placeholder exists.

Examples of safe checks:

  • verify that SDK_ACCESS_KEY variable exists;
  • verify that the relevant config key is present;
  • verify that the value is loaded from the expected config source;
  • verify generated metadata names without printing the full value.

Do not print the full SDK access key value unless the developer explicitly confirms that this is allowed by project policy.

Prefer redacted output when checking configuration.

Hard secrets

Hard secrets must never be committed, printed, copied into prompts, or included in the final report.

Hard secrets include:

  • Firebase Admin service account JSON;
  • APNs authentication keys;
  • APNs certificates;
  • private keys;
  • Reteno REST API credentials;
  • CI/CD secret values;
  • signing credentials.

Do not run broad commands that may expose hard secrets, such as:

cat <secret-config-file>
grep -R SERVICE_ACCOUNT .
grep -R PRIVATE_KEY .
grep -R APNS .

unless the command is scoped to show only filenames, variable names, or redacted output.

When checking local config files:

  • verify file presence without dumping full file contents;
  • verify variable names without printing hard secret values;
  • use redacted output for sensitive values;
  • do not include full secret values in logs, screenshots, terminal output, prompts, or final reports.

If a secret is accidentally printed in the agent session output:

  • report the exposure immediately;
  • mark it as a security warning / action required;
  • recommend rotating the exposed key or credential in the relevant provider dashboard;
  • do not repeat or copy the exposed value in the final report.

If the exposed value is a client-side SDK access key, follow the project policy for rotation.

If the exposed value is a hard server-side secret, mark it as a security warning / action required and recommend immediate rotation in the relevant provider dashboard.

SDK access key handling

Preferred Ionic SDK access key options:

  • plugin variable during plugin installation;
  • config.xml plugin variable for Ionic Cordova;
  • capacitor.config.ts / capacitor.config.json Cordova preferences for Ionic Capacitor;
  • approved local environment or build-time configuration;
  • JavaScript initialization only when approved by the developer and project policy.

Do not commit a real SDK access key unless this matches the project’s approved policy.

If the SDK access key is placed in config.xml or capacitor.config.* for a local dry run, document it in the final report and recommend moving it to the approved configuration method before production use.

Firebase and APNs security distinction

Distinguish between client configuration and server credentials.

Client configuration may include:

  • Android Firebase client configuration;
  • Apple-platform Firebase client configuration;
  • Firebase client API keys.

Client configuration may be included in the repository only when this matches the project policy.

Server credentials must never be committed, printed, copied into prompts, or included in the final report.

Server credentials include:

  • Firebase Admin service account JSON;
  • APNs authentication keys;
  • APNs certificates;
  • private keys;
  • Reteno REST API credentials.

If Reteno server-side Firebase or APNs configuration is missing, ask the developer or admin to configure it in the Reteno dashboard. Do not ask the developer to paste server credentials into the agent chat.

Developer Preparation Checklist

Before starting Ionic SDK integration, ask the developer to prepare or confirm the items below.

The agent must not ask for all values upfront if they can be detected from the project. However, the developer should make sure that the required project access, credentials, environment, and validation tools are available before the integration run starts.

1. Project access

The developer should provide or confirm:

  • access to the Ionic project repository;
  • the correct branch for the integration run;
  • whether the current branch can be modified;
  • whether a temporary local branch should be created;
  • whether the working tree is clean or contains unrelated changes;
  • whether the agent is allowed to install dependencies;
  • whether the agent is allowed to run Ionic CLI commands;
  • whether the agent is allowed to run Cordova CLI commands, if Ionic Cordova runtime is used;
  • whether the agent is allowed to run Capacitor CLI commands, if Ionic Capacitor runtime is used.

Do not continue with file modifications if branch or working tree safety is unclear.

2. Ionic framework and runtime

The developer should confirm:

  • Ionic framework type:
    • Angular;
    • React;
    • Vue;
  • active runtime:
    • Ionic Cordova;
    • Ionic Capacitor;
    • both indicators present, but one active runtime;
    • browser/PWA only;
  • whether native runtime exists for Android and/or iOS;
  • whether browser/PWA runtime is only for development preview;
  • which build commands should be used.

Do not use ionic serve or browser preview as evidence for native Reteno push validation.

3. Cordova / Capacitor ownership

For Ionic Cordova runtime, the developer should confirm:

  • installed Cordova platforms:
    • Android;
    • iOS;
    • both;
  • whether platforms/ folders are committed source or generated artifacts;
  • whether plugins/ folder is committed or generated;
  • whether Cordova platform regeneration is allowed;
  • whether plugin reinstall is allowed;
  • whether manual native changes may be overwritten by Ionic Cordova prepare or platform regeneration;
  • which Ionic Cordova commands should be used.

For Ionic Capacitor runtime, the developer should confirm:

  • installed Capacitor platforms:
    • Android;
    • iOS;
    • both;
  • whether native android/ and ios/ folders are committed source;
  • whether npx cap sync is allowed;
  • whether npx cap copy is allowed;
  • whether manual native changes may be overwritten by Capacitor sync/copy;
  • which Ionic Capacitor commands should be used.

Do not run native regeneration, prepare, sync, or copy commands without explicit developer approval.

4. Reteno app and SDK access key

The developer should confirm:

  • selected Reteno organization / workspace;
  • selected Reteno app/environment;
  • whether the Reteno app is for Android, iOS, or both;
  • token type configured for each selected Reteno app:
    • Android: FCM;
    • iOS: APNs or FCM;
  • whether development and production apps are separated;
  • approved method for providing the Reteno SDK access key;
  • whether debug mode may be enabled during the integration run.

Handle the Reteno SDK access key according to the project's approved configuration and repository policy.

For sandbox or validation-only configuration, clearly document whether the SDK access key is:

  • committed;
  • gitignored;
  • provided through local configuration;
  • provided through CI/CD or another build-time mechanism.

Do not unnecessarily expose the full SDK access key in prompts, logs, screenshots, terminal output, tool output, or final reports.

If sandbox SDK configuration is committed for an approved validation run, do not treat that configuration as production-ready automatically.

Document the required production SDK access key handoff in the final report.

5. Android / Firebase setup

For Android validation, the developer should confirm:

  • cordova-android version is 12.0.0 or higher, if Ionic Cordova Android is used;
  • Firebase project;
  • Android package name / applicationId;
  • google-services.json;
  • Reteno server-side Firebase configuration;
  • Google Services Gradle plugin can be applied or is already applied;
  • whether cordova-plugin-firebasex is installed;
  • whether @capacitor-firebase/messaging is installed;
  • whether another push plugin is required for app-specific behavior;
  • whether a custom FirebaseMessagingService exists;
  • Android test device or emulator;
  • Android 13+ notification permission can be requested at runtime.

6. iOS / APNs / Firebase setup

For iOS validation, the developer should confirm:

  • iOS deployment target is 15.0 or higher;
  • Xcode 15.0 or higher is available;
  • Swift 5.7 or higher is supported;
  • iOS bundle ID;
  • push route:
    • direct APNs;
    • Firebase / FCM with APNs transport;
  • selected IOS_DEVICE_TOKEN_HANDLING_MODE:
    • manual;
    • automatic;
  • GoogleService-Info.plist, if Firebase / FCM is used;
  • Firebase APNs credentials, if Firebase / FCM is used;
  • APNs sandbox / production route, if direct APNs is used;
  • Apple Developer Team ID, if required;
  • Push Notifications capability;
  • App Groups capability;
  • Notification Service Extension setup;
  • Notification Content Extension setup, if rich push UI is enabled;
  • extension Podfile changes are allowed;
  • signing/provisioning can be updated by the developer or admin.

7. Test environment

The developer should confirm the selected test environment:

  • Android emulator;
  • physical Android device;
  • iOS simulator, if supported and confirmed by the developer;
  • physical iOS device;
  • local Ionic Cordova build;
  • local Ionic Capacitor build;
  • CI build;
  • another supported environment.

The developer should confirm that:

  • the app can be built and installed;
  • Ionic native platform readiness can be verified;
  • Cordova or Capacitor native bridge works;
  • push permission can be requested;
  • push notifications can be enabled;
  • the developer or QA engineer can open the delivered test push notification if the agent cannot interact with the device directly;
  • the developer or QA engineer can complete login or registration if user identification validation is required.

8. Reteno MCP

The developer should confirm:

  • Reteno MCP is connected in the same environment where the AI coding agent runs;
  • the signed-in Reteno account has access to the selected organization / workspace;
  • the signed-in Reteno account has access to the selected Reteno app;
  • MCP capabilities can be discovered before validation;
  • manual Reteno UI fallback is available if a required MCP capability is missing.

Do not mark the integration as complete when a required Reteno-side result cannot be verified through Reteno MCP or any approved fallback evidence.

Missing MCP access alone is not a blocker when the required result can be independently verified through Reteno UI, backend data, SDK logs, device logs, redacted network evidence, or developer / QA confirmation.

9. Build and runtime logs

If the agent cannot build or run the app after safe diagnostics, or if the issue requires local environment access, the developer should provide:

  • exact Ionic CLI build error;
  • exact Cordova CLI or Capacitor CLI error, if applicable;
  • Android Studio / Gradle logs, if Android build fails;
  • Xcode / CocoaPods logs, if iOS build fails;
  • device, simulator, or emulator details;
  • Ionic runtime details;
  • Cordova or Capacitor platform details;
  • plugin list;
  • reproduction steps;
  • confirmation whether the issue is pre-existing or introduced by the integration.

Ionic SDK Integration Workflow

Follow this workflow for Ionic SDK integration.

1. Inspect the project

Before making changes, inspect the Ionic project.

Identify:

  • project structure;
  • package manager;
  • Ionic framework type:
    • Angular;
    • React;
    • Vue;
  • Ionic runtime type:
    • Cordova;
    • Capacitor;
    • both indicators present;
    • browser/PWA only;
    • unknown;
  • Ionic CLI version, if available;
  • package.json;
  • lockfile;
  • ionic.config.json;
  • config.xml, if Cordova runtime is used;
  • capacitor.config.ts or capacitor.config.json, if Capacitor runtime is used;
  • installed platforms;
  • installed plugins;
  • current cordova-plugin-reteno version, if installed;
  • current awesome-cordova-plugins-reteno version, if installed;
  • current @awesome-cordova-plugins/core version, if installed;
  • app entry point;
  • Ionic Platform.ready() location;
  • existing Reteno initialization, if any;
  • native platform folders;
  • whether native folders are committed;
  • Firebase / FCM setup;
  • existing google-services.json;
  • existing GoogleService-Info.plist;
  • existing push notification setup;
  • existing deeplink handling;
  • existing authentication or user identification flow;
  • existing In-App setup, if any;
  • files that may need to be updated.

Do not ask the developer for information that can be detected from project files.

2. Confirm Ionic runtime type

Classify the project before installing or configuring the SDK.

Use one of these classifications:

  • Ionic app with Cordova runtime;
  • Ionic app with Capacitor runtime;
  • Ionic app with both Cordova and Capacitor indicators;
  • pure Cordova app;
  • browser/PWA-only Ionic app;
  • non-Ionic project.

If the project is pure Cordova, stop and use the Cordova runbook instead.

If the project is browser/PWA-only, do not attempt native Reteno push validation.

If both Cordova and Capacitor indicators are present, stop before installing dependencies or modifying native files and ask the developer to confirm the active runtime.

3. Check whether Reteno Ionic SDK is already installed

If cordova-plugin-reteno or awesome-cordova-plugins-reteno is already installed, do not reinstall from scratch immediately.

Instead:

  • detect the current plugin version from project files, if possible;
  • detect the current wrapper version from package.json and lockfile;
  • check whether wrapper major matches @awesome-cordova-plugins/core major;
  • check plugin variables in config.xml, if Cordova runtime is used;
  • check Cordova preferences in capacitor.config.*, if Capacitor runtime is used;
  • check whether Android setup is complete;
  • check whether iOS setup is complete;
  • check whether initialization is already called after Platform.ready();
  • check whether push handling is configured;
  • check whether the current integration is incomplete, outdated, or misconfigured.

If Reteno Ionic SDK is not installed, continue with a new Ionic SDK integration flow.

4. Check SDK version and release notes

Before installing, updating, or troubleshooting the Reteno Ionic SDK:

  • detect the current cordova-plugin-reteno version, if installed;
  • detect the current awesome-cordova-plugins-reteno version, if installed;
  • check official Ionic SDK setup documentation;
  • check Ionic SDK / Cordova plugin release notes, if available;
  • check package registry metadata, if needed;
  • check whether the issue may be related to an outdated SDK version, compatibility issue, migration requirement, or known fixed issue.

Use the latest stable versions recommended by official Reteno documentation or package metadata.

Do not use pre-release, beta, alpha, or release-candidate versions unless the developer explicitly asks for it.

If documentation, release notes, and package registry versions differ, document the mismatch and ask the developer or platform owner which version to use.

Verify published wrapper package integrity

Do not assume that a successfully published or installed awesome-cordova-plugins-reteno version contains a usable compiled Angular wrapper.

For Ionic Angular, after selecting or installing the wrapper version, verify that the package exposes the Angular /ngx entry point required by the project.

Verify:

  • the installed package version;
  • package contents;
  • whether awesome-cordova-plugins-reteno/ngx resolves successfully;
  • whether compiled JavaScript and type declarations required by the /ngx entry point are present;
  • whether the wrapper can be imported by the current Ionic Angular build;
  • whether constructor injection works after provider registration.

Do not treat package-registry publication status alone as proof that the wrapper package is usable.

If the latest published wrapper version is missing the compiled /ngx output or otherwise cannot be consumed:

  • document the package publication defect;
  • check whether another published version in the same compatible major is usable;
  • do not downgrade or pin automatically without developer approval;
  • prefer a developer-approved known-working published version when available;
  • otherwise use an approved reproducible workaround, such as a repository-supported package patch or vendored build artifact;
  • document the workaround and the condition for removing it after an upstream fixed release.

Do not hardcode a permanent claim in this runbook that a specific wrapper version is broken.

Package publication contents may change between releases.

Document in the final report:

  • selected awesome-cordova-plugins-reteno version;
  • whether /ngx package integrity was verified;
  • whether the selected published package was usable;
  • whether a version pin, vendored wrapper, or package patch was required;
  • upstream-fix status, if known;
  • workaround removal condition.

5. Install the Cordova plugin and Ionic wrapper

Use the existing project workflow.

Do not switch package managers.

Do not generate another package manager's lockfile.

For Ionic Cordova runtime, install the Cordova plugin through Ionic Cordova:

ionic cordova plugin add cordova-plugin-reteno --variable SDK_ACCESS_KEY=YOUR_KEY

Install the Ionic wrapper:

npm install awesome-cordova-plugins-reteno @awesome-cordova-plugins/core

If @awesome-cordova-plugins/core is already installed, keep the existing major version and install the matching awesome-cordova-plugins-reteno major.

Do not upgrade @awesome-cordova-plugins/core across major versions without explicit developer approval.

For Ionic Capacitor runtime, install the Cordova plugin and sync only when approved:

npm install cordova-plugin-reteno
npm install awesome-cordova-plugins-reteno @awesome-cordova-plugins/core
npx cap sync

Do not run npx cap sync without explicit developer approval.

6. Configure SDK access key

For Ionic Cordova runtime, configure SDK_ACCESS_KEY through plugin variable or config.xml according to project policy:

<widget ...>
  <plugin name="cordova-plugin-reteno" spec="cordova-plugin-reteno">
    <variable name="SDK_ACCESS_KEY" value="YOUR_KEY" />
  </plugin>
</widget>

For Ionic Capacitor runtime, configure Cordova preferences in capacitor.config.ts when this matches project policy:

import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  cordova: {
    preferences: {
      SDK_ACCESS_KEY: 'YOUR_KEY'
    }
  }
};

export default config;

Do not commit a real SDK access key unless this matches the project’s approved policy.

If plugin variables or Capacitor preferences are changed, the native project may need prepare/sync.

Do not run prepare/sync without developer approval.

7. Initialize Reteno after Ionic platform readiness

Initialize Reteno only after the native platform is ready.

For Ionic Angular, use an app startup service, root component, or another stable bootstrap location after Platform.ready().

Before constructor injection, verify that the Reteno wrapper is registered in Angular providers.

7.1. Register the Reteno wrapper in Angular providers

For NgModule-based Ionic Angular apps:

import { NgModule } from '@angular/core';
import { AwesomeCordovaPluginReteno } from 'awesome-cordova-plugins-reteno/ngx';

@NgModule({
  providers: [AwesomeCordovaPluginReteno]
})
export class AppModule {}

For standalone Angular apps:

import { bootstrapApplication } from '@angular/platform-browser';
import { AwesomeCordovaPluginReteno } from 'awesome-cordova-plugins-reteno/ngx';

bootstrapApplication(AppComponent, {
  providers: [AwesomeCordovaPluginReteno]
});

This registration is mandatory.

Do not rely only on constructor injection.

If the wrapper is not registered, Angular can fail with NullInjectorError.

7.2. Inject and initialize after Ionic native readiness

Use the Angular /ngx entry point:

import { Platform } from '@ionic/angular';
import { AwesomeCordovaPluginReteno } from 'awesome-cordova-plugins-reteno/ngx';

constructor(
  private platform: Platform,
  private reteno: AwesomeCordovaPluginReteno
) {}

async initializeReteno(): Promise<void> {
  await this.platform.ready();

  await this.reteno.init({
    isDebugMode: false,
    pauseInAppMessages: false
  });
}

Do not import from the package root.

Do not initialize Reteno before Ionic native platform readiness.

Do not duplicate this.reteno.init(...).

If the project uses Ionic React or Ionic Vue, do not adapt the Angular DI example directly.

Ionic React and Ionic Vue are not covered by the Angular wrapper path. Treat them as framework-specific verification paths unless official Reteno Ionic documentation, project code, or an Ionic SME confirms the supported integration approach.

Expected result:

  • Reteno wrapper is registered in Angular providers;
  • initialization happens once;
  • initialization happens after native platform readiness;
  • SDK access key is available;
  • Cordova or Capacitor native bridge is ready;
  • existing app startup logic is preserved.

8. Request notification permission

When mobile push validation is included, request notification permission through the Ionic wrapper method:

const granted = await this.reteno.requestNotificationPermission();

Preserve the existing permission-prompt UX.

Do not show a duplicate permission prompt if the app already has an approved push permission flow.

Document where permission is requested in the final report.

9. Configure Android, if Android validation is included

Follow the Android setup section that matches the detected runtime:

10. Configure iOS, if iOS validation is included

Follow the iOS setup section that matches the detected runtime:

11. Configure push handling

Follow Ionic push handling.

12. Configure user identification, if required

Follow Ionic user identification.

13. Prepare or sync native platforms only when approved

For Ionic Cordova runtime, run prepare only when developer approval is explicit:

ionic cordova prepare android
ionic cordova prepare ios

For Ionic Capacitor runtime, run sync or copy only when developer approval is explicit:

npx cap sync android
npx cap sync ios

Before running prepare/sync/copy, report:

  • why it is required;
  • which runtime will be affected;
  • which platform will be affected;
  • whether native folders are committed;
  • whether manual native changes may be overwritten;
  • whether the developer approves the action.

Do not run platform remove/add unless explicitly approved.

13.1. Preserve required Capacitor native changes across sync

For Ionic Capacitor, do not assume that a manual change in android/ or ios/ survives:

npx cap sync

or:

npx cap copy

Before running Capacitor sync/copy, identify required manual native changes that may be regenerated or overwritten.

Examples may include:

  • Package.swift changes;
  • Podfile changes;
  • Xcode project configuration;
  • signing configuration;
  • provisioning-profile assignment;
  • Notification Service Extension configuration;
  • App Group configuration;
  • AndroidManifest changes;
  • Gradle changes;
  • native Firebase Messaging conflict fixes.

After every approved npx cap sync:

  1. inspect the affected native project again;
  2. verify that required Reteno configuration still exists;
  3. verify required Firebase configuration;
  4. verify notification-handler conflict fixes;
  5. verify native Reteno dependency versions;
  6. verify extension configuration, when applicable;
  7. rebuild when required.

Do not report a manual native change as surviving Capacitor sync only because npx cap sync was executed earlier in the integration run.

Durability must be evaluated against the ordering of the final native change.

For example:

npx cap sync
→ manual native fix
→ build

does not verify that the manual native fix survives the next sync.

In that case report:

Manual native changes survive npx cap sync: Not verified

Verified durability requires an approved sequence equivalent to:

npx cap sync
→ apply or reproduce the required native fix
→ npx cap sync
→ verify that the fix still exists or is automatically reapplied
→ rebuild / revalidate as required

Do not run the second sync only for durability testing unless the developer has approved it.

If another npx cap sync cannot safely be run:

  • do not infer durability;
  • report the result as Not verified;
  • document the native files affected;
  • document the expected loss or reapply risk;
  • define the required post-sync mechanism.

If the required change is produced by:

  • Capacitor configuration;
  • an idempotent post-sync script;
  • a project generation script;
  • a package patch;
  • another approved reproducible mechanism;

verify that the mechanism was actually exercised after the last relevant sync before reporting durability as passed.

The durability verdict must reflect the final state of the integration, not an earlier intermediate state.

If a required native fix does not survive sync, do not treat the manual native edit as a durable integration solution.

Prefer a developer-approved reproducible mechanism such as:

  • Capacitor configuration;
  • project-owned native configuration;
  • an idempotent post-sync script;
  • an existing project generation script;
  • a package-manager-supported patch;
  • another repository-approved mechanism.

If no durable mechanism can be implemented during the current integration:

  • document the exact native change;
  • document which Capacitor command removes it;
  • document the required reapply procedure;
  • mark the change as non-durable;
  • keep runtime validation result separate from merge readiness;
  • report the branch as not merge-ready when required Reteno, Firebase, push-handler, signing, extension, or native build configuration is neither tracked nor reproducibly generated from tracked project sources.

Developer acceptance of a manual reapply procedure may allow the current validation run to continue.

It does not make the integration reproducible or merge-ready.

Document in the final report:

  • whether required native changes survive Capacitor sync;
  • sync-sensitive files;
  • reapply mechanism;
  • whether the mechanism was tested after sync.

13.2. Verify native integration reproducibility before merge readiness

A successful local Android or iOS validation does not prove that the Ionic Capacitor integration is reproducible from the repository.

Before reporting:

Merge readiness: Ready

verify that every required native integration change is either:

  • tracked in the repository;
  • generated from tracked Capacitor or project configuration;
  • restored by a tracked project-owned script;
  • restored by an approved reproducible package patch;
  • restored by another tracked and reproducible project mechanism.

Required native state may include, depending on the current integration:

  • google-services.json placement;
  • Google Services Gradle configuration;
  • Android namespace or build-toolchain configuration;
  • Android manifest merge rules;
  • Firebase Messaging service ownership fixes;
  • iOS Firebase client configuration;
  • iOS entitlements;
  • App Groups;
  • Notification Service Extension;
  • Notification Content Extension, when required;
  • extension signing configuration that is representable in the project;
  • Podfile or Swift Package configuration;
  • native Reteno dependency linkage.

Do not require every example above when it is not part of the current integration.

Check whether required files are:

  • tracked;
  • intentionally gitignored;
  • generated;
  • recreated by npx cap sync;
  • recreated by npx cap add;
  • dependent on manual local changes.

If required native integration state exists only inside gitignored android/ or ios/ directories and no tracked reproducible mechanism restores it:

Runtime validation: Passed
Merge readiness: Not ready

is a valid result.

Do not convert:

Manual reapply documented

into:

Merge readiness: Ready

A manual checklist alone is not equivalent to reproducible repository state.

Do not modify .gitignore automatically.

If tracking currently ignored native files may be the correct solution:

  • document which files are required;
  • ask the developer or repository owner to approve the repository policy change.

If a post-sync or generation script is the intended solution:

  • make it project-owned;
  • make it deterministic and idempotent when practical;
  • document when it runs;
  • verify that it restores the required native Reteno configuration;
  • test it after an approved sync when possible.

Document:

  • required native files or configuration that are ignored;
  • whether each required change is tracked or reproducible;
  • reproduction mechanism;
  • whether the mechanism was actually tested;
  • resulting merge-readiness decision.

14. Build and run the application

Use the selected supported test environment.

Do not use ionic serve, browser preview, or PWA runtime for native Reteno push validation.

Possible build/run commands may include:

ionic cordova build android
ionic cordova run android
ionic cordova build ios
ionic cordova run ios
ionic capacitor build android
ionic capacitor run android
ionic capacitor build ios
ionic capacitor run ios

Use the project’s existing scripts when available.

If build/run fails, do not repeat the same failed action without a new hypothesis.

Continue safe diagnostics while distinct testable causes remain.

Escalate when the issue requires local environment access, external access, credentials, signing, Apple Developer account access, Firebase server configuration, Reteno dashboard changes, GUI interaction, Cordova platform regeneration, Capacitor sync, or manual device actions.

When escalation is required, ask the developer to run the app through Ionic CLI, Cordova CLI, Capacitor CLI, Android Studio, Xcode, Gradle, CocoaPods, or the relevant project tool and provide:

  • exact build or runtime error;
  • crash reason, if available;
  • Ionic CLI logs;
  • Cordova or Capacitor CLI logs;
  • Gradle logs, if Android build fails;
  • Xcode / CocoaPods logs, if iOS build fails;
  • relevant native logs;
  • device, simulator, or emulator details;
  • reproduction steps.

15. Continue validation

After the app builds and runs, continue with MCP Capability Discovery and Validation.

Do not mark the integration as complete until required validation checks pass or a blocker is clearly documented.

Ionic Cordova Android setup

Use this section when Android validation is included and the active runtime is Ionic Cordova.

Follow the official Reteno Ionic Android SDK setup.

1. Verify Android prerequisites

Before Android setup, verify:

  • active runtime is Ionic Cordova;
  • cordova-android version;
  • Android package name / applicationId;
  • google-services.json;
  • Firebase / FCM setup;
  • Reteno app configured for Android / FCM;
  • Android 13+ notification permission flow;
  • whether platforms/android exists;
  • whether platforms/android is committed;
  • whether ionic cordova prepare android is approved;
  • whether ionic cordova platform rm/add android is approved;
  • selected Android test environment.

2. Cordova Android version

Reteno Ionic Android setup requires:

cordova-android >= 12.0.0

Older Cordova Android platforms may refuse to install the plugin or may not support the required Android configuration.

Do not upgrade cordova-android without explicit developer approval.

Treat a Cordova Android platform upgrade as a product/build compatibility decision.

Document the detected cordova-android version in the final report.

3. Install or configure plugin for Android

Use the project’s existing Ionic Cordova plugin management approach.

Example:

ionic cordova plugin add cordova-plugin-reteno --variable SDK_ACCESS_KEY=YOUR_KEY

Or configure in config.xml:

<plugin name="cordova-plugin-reteno" spec="cordova-plugin-reteno">
  <variable name="SDK_ACCESS_KEY" value="YOUR_KEY" />
</plugin>

Do not commit a real SDK access key unless this matches the project’s approved policy.

If plugin variables are changed after installation, Ionic Cordova may require plugin reinstall or platform regeneration.

Do not run plugin reinstall or platform regeneration without developer approval.

4. Android Firebase / FCM setup

Verify that google-services.json exists and belongs to the correct Firebase project and Android application ID.

Expected Ionic Cordova Android path after platform setup:

platforms/android/app/google-services.json

Verify that Google Services Gradle plugin is applied.

Expected evidence may include:

  • build file references to com.google.gms.google-services;
  • successful build logs;
  • absence of google-services.json not found errors.

If google-services.json is missing or mismatched:

  • do not invent one;
  • ask the developer to provide the correct Firebase client config;
  • document the blocker in the final report.

Do not ask the developer to paste Firebase Admin service account JSON into the repository or prompt.

5. Android 13+ notification permission

For Android 13+ and targetSdkVersion >= 33, runtime notification permission is required.

The plugin may inject POST_NOTIFICATIONS into the manifest, but the app still needs to request permission at runtime.

Use:

const granted = await this.reteno.requestNotificationPermission();

Preserve existing permission prompt UX.

Do not duplicate prompts.

Document the permission request location in the final report.

6. Firebasex and push-handler conflict check

If cordova-plugin-firebasex or another push plugin is installed, inspect whether it registers its own FirebaseMessagingService.

On Android, only one service receives com.google.firebase.MESSAGING_EVENT unless Firebase Messaging multiplexing or manifest configuration safely supports multiple handlers.

Do not remove Firebasex automatically.

If Firebasex is required for app-specific behavior:

  • preserve it;
  • document the possible conflict;
  • ask an Android/Ionic SME to confirm the correct integration path;
  • verify whether Reteno still receives token and push callbacks.

If Firebasex was installed only for push delivery and Reteno should handle push instead, ask the developer whether Firebasex can be removed or reconfigured.

7. Custom Firebase Messaging Service

Most Ionic Cordova apps do not need a custom FirebaseMessagingService for Reteno.

If custom native FCM handling is required, use the official Reteno Ionic / Cordova Android setup.

The custom service must preserve existing app-specific logic and call the required Reteno handling path according to the official docs.

Do not create duplicate MESSAGING_EVENT services.

Do not replace existing app-specific native logic without developer approval.

8. Android build and run

Build and run with:

ionic cordova build android
ionic cordova run android

or with the project’s existing Android build command.

Expected result:

  • app builds;
  • app installs;
  • app launches;
  • Ionic native platform readiness is reached;
  • SDK initializes;
  • contact is created;
  • mobilePushToken is assigned;
  • token type is FCM;
  • test push can be sent and validated.

Ionic Capacitor Android setup

Use this section when Android validation is included and the active runtime is Ionic Capacitor.

Do not assume Cordova plugin hooks run in Capacitor.

Some automatic Cordova setup steps must be completed manually or verified after npx cap sync.

1. Verify Android prerequisites

Before Android setup, verify:

  • active runtime is Ionic Capacitor;
  • capacitor.config.ts or capacitor.config.json;
  • Android package name / applicationId;
  • google-services.json;
  • Firebase / FCM setup;
  • Reteno app configured for Android / FCM;
  • Android 13+ notification permission flow;
  • whether native android/ folder exists;
  • whether native android/ folder is committed;
  • whether npx cap sync android is approved;
  • whether manual native Android changes are allowed;
  • selected Android test environment.

1.1. Verify Android build-toolchain compatibility

Before changing Android build tooling, inspect the existing project configuration.

Record:

  • Capacitor Android version;
  • Gradle wrapper version;
  • Android Gradle Plugin version;
  • Java / JDK version used by Gradle;
  • Kotlin version, when applicable;
  • compileSdk;
  • targetSdk;
  • minSdk;
  • Android namespace configuration;
  • Reteno Android dependency requirements visible in the resolved build.

Do not assume that every Android build-toolchain incompatibility is caused by Reteno.

Classify the actual failure before changing versions:

  • Reteno/native dependency requirement;
  • Capacitor framework requirement;
  • Android Gradle Plugin requirement;
  • Gradle/JDK compatibility issue;
  • pre-existing project mismatch;
  • unrelated plugin compatibility issue.

Do not automatically upgrade:

  • Gradle;
  • Android Gradle Plugin;
  • Java/JDK;
  • Kotlin;
  • compileSdk;
  • targetSdk;
  • minSdk.

Treat these changes as project/build compatibility decisions.

Ask for developer approval before changing the supported Android build toolchain.

If a Reteno transitive dependency requires a higher compileSdk:

  • identify the exact build error or dependency requirement;
  • document the current compileSdk;
  • document the minimum required build SDK;
  • ask the developer to approve the change;
  • do not automatically change targetSdk or minSdk unless the project also requires it.

If upgrading Android Gradle Plugin introduces a namespace requirement:

  • do not manually patch multiple dependency packages without checking whether newer compatible package versions exist;
  • preserve existing application namespace;
  • use a durable approved workaround if third-party modules require temporary namespace fixes.

Document in the final report:

  • original build-toolchain versions;
  • final build-toolchain versions;
  • which change was required by Reteno or a Reteno dependency;
  • which change was pre-existing or unrelated to Reteno;
  • developer approval for compatibility changes.

2. Install plugin and wrapper

Install the Cordova plugin and Ionic wrapper using the existing package manager.

Example:

npm install cordova-plugin-reteno
npm install awesome-cordova-plugins-reteno @awesome-cordova-plugins/core

If @awesome-cordova-plugins/core is already installed, keep the existing major version and install the matching Reteno wrapper major.

Do not switch package managers.

Do not run npx cap sync android until the developer approves it.

3. Configure SDK access key in Capacitor config

Configure Cordova preferences in capacitor.config.ts or capacitor.config.json.

Example:

import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  cordova: {
    preferences: {
      SDK_ACCESS_KEY: 'YOUR_KEY'
    }
  }
};

export default config;

Do not commit a real SDK access key unless this matches the project’s approved policy.

The plugin may read generated Capacitor config during native build.

After changing Capacitor config, run npx cap sync android only with approval.

4. Add google-services.json manually

Cordova hook that auto-copies google-services.json does not run in Capacitor.

The expected path is:

android/app/google-services.json

Verify that:

  • file exists;
  • file belongs to the correct Firebase project;
  • file matches the effective Android application ID;
  • generated native project uses the correct file after npx cap sync android.

If the file is missing or mismatched:

  • do not invent one;
  • ask the developer to provide the correct Firebase client config;
  • document the blocker in the final report.

5. Verify Google Services Gradle plugin

Check whether Google Services Gradle plugin is applied in the generated or committed Android project.

Expected evidence may include:

apply plugin: 'com.google.gms.google-services'

or equivalent Gradle plugin configuration.

If missing, ask the developer or Android/Ionic SME to confirm the correct setup path.

Do not blindly add Gradle plugins if the project already uses a different Firebase Messaging integration.

5.1. Verify Android FCM message-handler ownership

If any Firebase Messaging or push-notification integration is installed, inspect the final merged Android manifest.

Relevant integrations may include:

  • @capacitor-firebase/messaging;
  • @capacitor/push-notifications;
  • cordova-plugin-firebasex;
  • legacy Cordova FCM plugins;
  • a custom FirebaseMessagingService;
  • another Cordova or Capacitor push plugin;
  • application-owned native Firebase Messaging code.

Legacy plugin examples may include packages such as:

cordova-plugin-fcm-with-dependecy-updated

Treat package names as detection examples only.

Do not assume that a listed plugin always conflicts with Reteno.

Determine actual service ownership from the final merged Android manifest and runtime behavior.

Search for services that register:

<intent-filter>
    <action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>

Do not validate service ownership only from package.json.

Verify the final merged manifest used by the Android build.

Record:

  • every FirebaseMessagingService implementation registered for com.google.firebase.MESSAGING_EVENT;
  • manifest merge priority, when present;
  • which service receives the actual incoming Reteno push;
  • whether Reteno's RetenoFirebaseMessagingService receives the payload.

Do not assume that a valid FCM token or backend DELIVERED status proves that Reteno owns Android notification processing.

A handler conflict may produce this failure signature:

  • mobilePushToken exists;
  • token type is FCM;
  • test send succeeds;
  • Reteno-side delivery evidence may exist;
  • no Reteno notification appears in the system tray;
  • RetenoNotificationClickedActivity never runs;
  • CLICKED cannot be produced.

If another Firebase Messaging service prevents Reteno from handling Reteno notification payloads:

  • do not remove the entire plugin automatically;
  • determine whether the existing plugin is still required for token retrieval or other application behavior;
  • ask the developer to approve the native manifest change;
  • remove or disable only the conflicting FirebaseMessagingService registration when that is the approved integration design;
  • preserve the JavaScript/token API of the existing plugin when it is still required.

A project may use an Android manifest merge rule such as tools:node="remove" only when:

  • the conflicting service has been identified;
  • Reteno is intended to own Reteno message processing;
  • the developer approves the change;
  • application-specific behavior is preserved.

After the change:

  1. rebuild the Android application;
  2. verify the merged manifest again;
  3. send a new test push;
  4. confirm a real system-tray notification appears;
  5. open the notification;
  6. verify RetenoNotificationClickedActivity or equivalent Reteno click handling;
  7. verify CLICKED.

Do not treat DELIVERED alone as proof of successful Android notification presentation or interaction handling.

Document in the final report:

  • detected FCM services;
  • final Reteno message-handler owner;
  • whether a conflict was found;
  • how the conflict was resolved;
  • whether the existing Firebase plugin was preserved;
  • whether a real system-tray notification was verified;
  • whether CLICKED passed after the fix.

6. Sync Android only when approved

Run:

npx cap sync android

only when the developer approves it.

Before sync, document:

  • why sync is required;
  • whether native android/ is committed;
  • whether manual native changes may be overwritten;
  • whether the developer approved the action.

7. Android build and run

Build and run with:

ionic capacitor build android
ionic capacitor run android

or with the project’s existing Android build command.

Expected result:

  • app builds;
  • app installs;
  • app launches;
  • Capacitor native bridge is available;
  • SDK initializes;
  • contact is created;
  • mobilePushToken is assigned;
  • token type is FCM;
  • test push can be sent and validated.

Ionic Cordova iOS setup

Use this section when iOS validation is included and the active runtime is Ionic Cordova.

Follow the official Reteno Ionic iOS SDK setup and Cordova iOS setup requirements.

1. Verify iOS prerequisites

Before iOS setup, verify:

  • active runtime is Ionic Cordova;
  • iOS deployment target;
  • Xcode version;
  • Swift version;
  • iOS bundle identifier;
  • push route:
    • direct APNs;
    • Firebase / FCM with APNs transport;
  • selected IOS_DEVICE_TOKEN_HANDLING_MODE:
    • manual;
    • automatic;
  • GoogleService-Info.plist, if Firebase / FCM is used;
  • Apple Developer Team ID, if required;
  • Push Notifications capability;
  • App Groups capability;
  • Notification Service Extension setup;
  • Notification Content Extension setup, if rich push UI is enabled;
  • extension Podfile setup;
  • selected iOS test environment.

2. Minimum iOS requirements

Reteno Ionic iOS setup requires:

iOS 15.0+
Xcode 15.0+
Swift 5.7+

In config.xml, verify or add:

<preference name="deployment-target" value="15.0" />

Do not raise the iOS deployment target without developer approval.

Treat deployment target increase as a product compatibility decision.

If pod install fails because a higher minimum deployment target is required, ask the developer to approve raising deployment target to 15.0 or higher.

3. Install or configure plugin for iOS

Use the project’s existing Ionic Cordova plugin management approach.

Example:

ionic cordova plugin add cordova-plugin-reteno --variable SDK_ACCESS_KEY=YOUR_KEY

Or configure in config.xml:

<plugin name="cordova-plugin-reteno" spec="cordova-plugin-reteno">
  <variable name="SDK_ACCESS_KEY" value="YOUR_KEY" />
</plugin>

Do not commit a real SDK access key unless this matches the project’s approved policy.

If plugin variables are changed after installation, Ionic Cordova may require plugin reinstall or platform regeneration.

Do not run plugin reinstall or platform regeneration without developer approval.

4. iOS token handling mode

For Ionic Cordova iOS, explicitly choose and document IOS_DEVICE_TOKEN_HANDLING_MODE.

Supported modes:

manual
automatic

Use:

<preference name="IOS_DEVICE_TOKEN_HANDLING_MODE" value="manual" />

or:

<preference name="IOS_DEVICE_TOKEN_HANDLING_MODE" value="automatic" />

Use manual when the app uses Firebase / FCM token forwarding or when another SDK/plugin owns token retrieval.

Use automatic only when the app intentionally uses APNs-only token handling by the native Reteno SDK.

The mode is read from iOS preferences during this.reteno.init(...).

It cannot be changed at runtime from TypeScript after plugin start.

If this preference changes, run ionic cordova prepare ios and rebuild the iOS app only after developer approval.

Document the selected mode in the final report.

5. Firebase / FCM on iOS

If the app uses Firebase / FCM for iOS push delivery:

  • verify GoogleService-Info.plist;
  • verify that it belongs to the correct Firebase project and iOS bundle ID;
  • verify Firebase has valid APNs credentials;
  • verify Reteno uses the corresponding Firebase project;
  • verify APNs and FCM tokens are not mixed;
  • use IOS_DEVICE_TOKEN_HANDLING_MODE=manual unless official docs and developer confirmation require otherwise.

If another plugin obtains the FCM token and the automatic forwarding path does not work, forward the token manually:

await this.reteno.setDeviceToken(token);

Do not mark iOS FCM push setup as complete until the selected token path is verified.

Expected result:

  • Reteno receives an FCM token, not an APNs token;
  • token type matches the selected Reteno mobile app configuration;
  • mobilePushToken is assigned to the correct contact.

6. Direct APNs on iOS

If the app uses direct APNs:

  • verify selected Reteno app is configured for APNs;
  • verify token type is APNs;
  • verify APNs sandbox / production route;
  • use IOS_DEVICE_TOKEN_HANDLING_MODE=automatic only when APNs-only token handling is intended and confirmed.

Do not treat missing DELIVERED as an SDK integration issue until APNs sandbox/production routing is confirmed.

7. iOS App Group naming

Use the required Reteno shared-storage App Group format:

group.<main-app-bundle-id>.reteno-local-storage

Use the main app bundle ID.

Do not use the Notification Service Extension bundle ID.

Do not add an extension suffix.

Example:

Main app bundle ID:
com.example.app

Required Reteno App Group:
group.com.example.app.reteno-local-storage

Apply the same App Group to:

  • the main app target;
  • Notification Service Extension;
  • Notification Content Extension, if created.

Expected result:

  • all required targets share the same Reteno App Group;
  • the App Group uses the main app bundle ID;
  • the App Group does not use the extension bundle ID;
  • Reteno shared storage works between app and extensions.

8. Notification Service Extension and extension Podfile

For iOS push delivery and rich push behavior, verify Notification Service Extension setup.

The extension target must include Reteno.

Example Podfile structure:

target 'App' do
  # ... existing pods ...

  target 'NotificationServiceExtension' do
    inherit! :search_paths
    pod 'Reteno', '2.7.3'
  end

  target 'NotificationContentExtension' do
    inherit! :search_paths
    pod 'Reteno', '2.7.3'
  end
end

The extension target Reteno pod version must match the native iOS Reteno pod version declared by the installed plugin.

Before editing the Podfile, inspect the currently installed plugin:

plugins/cordova-plugin-reteno/plugin.xml

Find the Reteno iOS pod declaration:

<pod name="Reteno" spec="..." />

Use the same spec value in every extension target.

Do not leave the extension target pod unpinned.

Do not use a newer Reteno pod version for the extension target unless the plugin, release notes, and iOS/Ionic SME confirm the version match.

Expected result:

  • main app target and extension targets use the same native Reteno iOS SDK version;
  • Notification Service Extension builds with the same Reteno SDK version as the main target;
  • native SDK mismatch between app and extension is avoided.

Use the Reteno iOS SDK version required by the current Ionic / Cordova plugin documentation.

Do not assume extension targets receive Reteno automatically from the main plugin setup.

After Podfile changes, run CocoaPods commands only when allowed by the developer.

If pod install fails because specs are outdated, use:

pod install --repo-update

from the iOS platform directory, or pass -- --repo-update to the Ionic Cordova iOS build command when appropriate.

9. iOS permission request

When mobile push validation is included, request notification permission through the Ionic wrapper method:

const granted = await this.reteno.requestNotificationPermission();

Preserve existing permission prompt UX.

Do not duplicate prompts.

Document where permission is requested in the final report.

10. iOS foreground and tap behavior

If the app needs custom foreground or tap handling, configure it from TypeScript only when official docs and developer confirmation require it.

Preserve existing app notification handling.

Do not create duplicate routing.

Do not replace existing Ionic router, deeplink, local notification, or Firebase Messaging behavior without developer confirmation.

11. iOS build and run

Build and run with:

ionic cordova build ios
ionic cordova run ios

or with the project’s existing iOS build command.

Expected result:

  • app builds;
  • app installs;
  • app launches;
  • Ionic native platform readiness is reached;
  • SDK initializes;
  • contact is created;
  • mobilePushToken is assigned;
  • token type is APNs or FCM, depending on selected route;
  • test push can be sent and validated.

Ionic Capacitor iOS setup

Use this section when iOS validation is included and the active runtime is Ionic Capacitor.

Do not assume Cordova plugin hooks run in Capacitor.

Some automatic Cordova setup steps must be completed manually or verified after npx cap sync.

1. Verify iOS prerequisites

Before iOS setup, verify:

  • active runtime is Ionic Capacitor;
  • capacitor.config.ts or capacitor.config.json;
  • iOS bundle identifier;
  • iOS deployment target;
  • Xcode version;
  • Swift version;
  • push route:
    • direct APNs;
    • Firebase / FCM with APNs transport;
  • selected IOS_DEVICE_TOKEN_HANDLING_MODE:
    • manual;
    • automatic;
  • GoogleService-Info.plist, if Firebase / FCM is used;
  • Push Notifications capability;
  • App Groups capability;
  • Notification Service Extension setup;
  • Notification Content Extension setup, if rich push UI is enabled;
  • active iOS dependency manager:
    • CocoaPods;
    • Swift Package Manager;
    • mixed;
    • unknown;
  • Reteno native iOS dependency configuration for the detected dependency manager;
  • whether the Reteno native iOS SDK version resolved by the main app matches the version required by the installed cordova-plugin-reteno;
  • extension Reteno dependency configuration, when an extension target is required;
  • whether native ios/ folder exists;
  • whether native ios/ folder is committed;
  • whether npx cap sync ios is approved;
  • whether manual native iOS changes are allowed;
  • selected iOS test environment.

2. Install plugin and wrapper

Install the Cordova plugin and Ionic wrapper using the existing package manager.

Example:

npm install cordova-plugin-reteno
npm install awesome-cordova-plugins-reteno @awesome-cordova-plugins/core

If @awesome-cordova-plugins/core is already installed, keep the existing major version and install the matching Reteno wrapper major.

Do not switch package managers.

Do not run npx cap sync ios until the developer approves it.

3. Configure SDK access key and iOS preferences in Capacitor config

Configure Cordova preferences in capacitor.config.ts or capacitor.config.json.

Example:

import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  cordova: {
    preferences: {
      SDK_ACCESS_KEY: 'YOUR_KEY',
      IOS_DEVICE_TOKEN_HANDLING_MODE: 'manual'
    }
  }
};

export default config;

Do not commit a real SDK access key unless this matches the project’s approved policy.

After changing Capacitor config, run npx cap sync ios only with developer approval.

4. Firebase / FCM on iOS

If the app uses Firebase / FCM for iOS push delivery:

  • verify GoogleService-Info.plist;
  • verify that it belongs to the correct Firebase project and iOS bundle ID;
  • verify Firebase has valid APNs credentials;
  • verify Reteno uses the corresponding Firebase project;
  • use IOS_DEVICE_TOKEN_HANDLING_MODE=manual unless official docs and developer confirmation require otherwise;
  • pass the FCM token to Reteno through this.reteno.setDeviceToken(token) when another plugin owns token retrieval.

Expected result:

  • Firebase obtains an FCM token;
  • Reteno receives the FCM token;
  • Reteno-side token type is FCM;
  • APNs and FCM tokens are not mixed.

4.1. Determine FCM token ownership before calling setDeviceToken(...)

Do not determine whether this.reteno.setDeviceToken(...) is required only from:

IOS_DEVICE_TOKEN_HANDLING_MODE=manual

First determine which component owns FCM token retrieval and forwarding in the current Ionic Capacitor application.

Possible token owners include:

  • Reteno / the installed Reteno plugin's internal Firebase Messaging integration;
  • @capacitor-firebase/messaging;
  • another Firebase or push plugin;
  • application-specific native code;
  • application-specific TypeScript code.

Reteno/plugin-managed token path

If the selected Reteno plugin version internally obtains the Firebase token and automatically forwards it to Reteno:

  • do not add a second setDeviceToken(...) call only because token handling mode is manual;
  • verify that the final Reteno contact receives an FCM token;
  • verify token refresh behavior when relevant;
  • preserve the working plugin-managed path.

External token-owner path

If another plugin or application code owns FCM token retrieval:

  • obtain the FCM token through that existing owner;
  • forward the token to Reteno through:
await this.reteno.setDeviceToken(token);
  • preserve the existing token owner when it is required by the application;
  • verify token refresh forwarding when applicable.

Do not use both automatic plugin forwarding and explicit application forwarding unless the selected SDK documentation or current project behavior requires both.

Duplicate token-forwarding paths may create ambiguous or stale token state.

Expected result:

  • token owner is identified;
  • exactly one intentional Reteno token-forwarding path is used;
  • Reteno receives an FCM token for the Firebase route;
  • final mobilePushToken matches the selected Reteno mobile app configuration.

Document in the final report:

  • FCM token owner;
  • whether plugin-managed forwarding was used;
  • whether this.reteno.setDeviceToken(...) was required;
  • whether this.reteno.setDeviceToken(...) was invoked;
  • final Reteno token type.

5. Direct APNs on iOS

If the app uses direct APNs:

  • verify selected Reteno app is configured for APNs;
  • verify token type is APNs;
  • verify APNs sandbox / production route;
  • use IOS_DEVICE_TOKEN_HANDLING_MODE=automatic only when APNs-only token handling is intended and confirmed.

Do not treat missing DELIVERED as an SDK integration issue until APNs sandbox/production routing is confirmed.

6. Add and verify Notification Service Extension manually

Cordova hooks may not create or configure iOS extension targets in Capacitor projects.

Verify or manually configure, with developer approval:

  • Notification Service Extension target;
  • Notification Content Extension target, if rich push UI is required;
  • extension bundle identifiers;
  • extension deployment target;
  • extension entitlements;
  • App Groups;
  • native dependency configuration for the active dependency manager:
    • CocoaPods;
    • Swift Package Manager;
    • mixed;
  • Reteno dependency linked to extension target.

Do not create or modify extension targets without developer approval.

Do not assume Capacitor sync handles extension targets automatically.

7. App Group naming

Use the required Reteno shared-storage App Group format:

group.<main-app-bundle-id>.reteno-local-storage

Apply the same App Group to:

  • main app target;
  • Notification Service Extension;
  • Notification Content Extension, if created.

Do not use the extension bundle ID in the App Group name.

Do not add an extension suffix.

8. Reteno dependency setup for iOS extension targets

First detect how the current Ionic Capacitor iOS project resolves native dependencies.

Supported project patterns may include:

  • CocoaPods;
  • Swift Package Manager;
  • mixed CocoaPods / Swift Package Manager setup.

Do not require a Podfile when the current Capacitor iOS project uses Swift Package Manager.

Before configuring an extension target, determine the native Reteno iOS SDK version required by the currently installed cordova-plugin-reteno.

Use the installed plugin metadata and resolved native project dependencies as the source of truth.

The main application target and every Reteno extension target must resolve a compatible Reteno iOS SDK version.

CocoaPods path

When the active project uses CocoaPods, verify that each required extension target explicitly includes Reteno.

Example:

target 'App' do
  # ... existing pods ...

  target 'NotificationServiceExtension' do
    inherit! :search_paths
    pod 'Reteno', '<resolved-Reteno-iOS-version>'
  end

  target 'NotificationContentExtension' do
    inherit! :search_paths
    pod 'Reteno', '<resolved-Reteno-iOS-version>'
  end
end

Before setting the version, inspect the installed plugin metadata and use the Reteno iOS SDK version required by that plugin.

Do not copy an older hardcoded pod version from this runbook.

Verify the final resolution through Podfile.lock when available.

Swift Package Manager path

When the active project uses Swift Package Manager:

  • do not create a Podfile only for Reteno;
  • inspect Package.swift, Xcode package dependencies, Package.resolved, or generated Capacitor package configuration;
  • verify which Reteno iOS SDK version is resolved for the main application target;
  • verify that the required extension target links the Reteno package/product;
  • verify that the extension resolves a compatible Reteno iOS SDK version.

If Capacitor or the Cordova compatibility layer generates Package.swift, determine whether manual changes survive npx cap sync ios.

Do not treat a manual edit to generated Package.swift as durable unless the project preserves or reapplies that change reproducibly.

Mixed dependency-manager path

If the project contains both CocoaPods and Swift Package Manager:

  • identify which dependency manager owns Reteno;
  • do not add Reteno through both managers unless the existing project explicitly requires this;
  • avoid duplicate native Reteno SDK linkage;
  • verify final resolved native versions from the built project.

Expected result:

  • the active dependency manager is identified;
  • the main app target resolves the Reteno iOS SDK required by the selected plugin;
  • each required extension target links Reteno through the correct dependency manager;
  • main app and extension targets use compatible Reteno versions;
  • no duplicate CocoaPods/SPM Reteno integration is introduced.

Document in the final report:

  • active iOS dependency manager;
  • resolved main-app Reteno iOS SDK version;
  • extension dependency mechanism;
  • resolved extension Reteno version;
  • whether main-app and extension versions match;
  • whether dependency configuration survives npx cap sync ios.

9. Sync iOS only when approved

Run:

npx cap sync ios

only when the developer approves it.

Before sync, document:

  • why sync is required;
  • whether native ios/ is committed;
  • whether manual native changes may be overwritten;
  • whether the developer approved the action.

10. iOS build and run

Build and run with:

ionic capacitor build ios
ionic capacitor run ios

or with the project’s existing iOS build command.

Expected result:

  • app builds;
  • app installs;
  • app launches;
  • Capacitor native bridge is available;
  • Ionic native platform readiness is reached;
  • SDK initializes;
  • contact is created;
  • mobilePushToken is assigned;
  • token type is APNs or FCM, depending on selected route;
  • test push can be sent and validated.

Ionic push handling

Use this section when mobile push validation is included.

Follow the official Reteno Ionic push handling documentation and the selected runtime setup.

Ionic push handling API methods to verify

When push handling, custom push data, notification opening, or action buttons are part of the current integration task, verify the actual Reteno Ionic API methods supported by the installed wrapper version.

Relevant methods may include:

getInitialNotification()

setOnRetenoPushReceivedListener()
removeOnRetenoPushReceivedListener()

setOnRetenoNotificationClickedListener()
removeOnRetenoNotificationClickedListener()

setOnRetenoPushButtonClickedListener()
removeOnRetenoPushButtonClickedListener()

setNotificationActionHandler()

Use these methods only when they exist in the installed wrapper and are documented for the selected SDK version.

Recommended mapping:

  • initial notification / cold-start payload:
    • getInitialNotification();
  • foreground push handling:
    • setOnRetenoPushReceivedListener(...);
    • removeOnRetenoPushReceivedListener(...);
  • notification click handling:
    • setOnRetenoNotificationClickedListener(...);
    • removeOnRetenoNotificationClickedListener(...);
  • action button handling:
    • setOnRetenoPushButtonClickedListener(...);
    • removeOnRetenoPushButtonClickedListener(...);
    • setNotificationActionHandler(...).

Do not validate foreground push, custom push data, click handling, or action buttons without naming the method used.

If a method is not exposed by the installed wrapper version, document it as:

not available in selected wrapper version

Do not treat a missing method as validation failure until wrapper version and official documentation are checked.

Document in the final report:

  • which push handling methods were registered;
  • which methods were removed or cleaned up;
  • which app state was tested:
    • foreground;
    • background;
    • terminated / cold start;
  • which evidence source confirmed each result.

For Ionic Capacitor iOS, the installed wrapper may also expose:

setWillPresentNotificationOptions(...)

setDidReceiveNotificationResponseHandler({
  enabled: true
})

Treat these as Capacitor iOS notification-handler APIs, not universal Ionic push requirements.

Verify method availability in the installed wrapper before using them.

1. Push registration

After SDK integration, verify that the app registers for remote notifications through the selected Ionic / native setup.

Expected result:

  • Ionic native platform readiness is reached;
  • SDK initializes;
  • notification permission can be requested;
  • push token is obtained;
  • push token is passed to Reteno through the selected platform route;
  • Reteno contact has mobilePushToken;
  • token type matches the selected Reteno app configuration.

2. Initialization and permission order

Use this order when mobile push validation is part of the current integration task:

  1. Wait for Ionic native platform readiness.
  2. Initialize Reteno once.
  3. Register required listeners for the current integration task.
  4. Request notification permission.
  5. Verify token assignment.
  6. Send test push.
  7. Verify DELIVERED.
  8. Open the delivered push.
  9. Verify CLICKED.

Do not initialize Reteno before the native bridge is ready.

Do not request notification permission before Reteno initialization when the official setup requires SDK initialization first.

Preserve the existing permission-prompt UX.

3. Android push handling

For Android, expected token type is:

FCM

Verify:

  • Android Firebase setup is correct;
  • google-services.json matches the effective Android application ID;
  • Google Services Gradle plugin is applied;
  • cordova-android version is 12.0.0 or higher when Ionic Cordova runtime is used;
  • Capacitor Android manual Firebase setup is complete when Ionic Capacitor runtime is used;
  • notification permission is handled on Android 13+;
  • Firebasex, Capacitor Firebase Messaging, or another push plugin does not block Reteno FCM callbacks;
  • notification is shown on-device;
  • DELIVERED and CLICKED evidence can be verified.

4. iOS push handling

For iOS, expected token type is:

APNs

or:

FCM

depending on selected push route and token handling mode.

Verify:

  • deployment target is 15.0 or higher;
  • IOS_DEVICE_TOKEN_HANDLING_MODE is selected and documented;
  • App Groups are configured;
  • Notification Service Extension is configured when required by the selected Reteno feature or validation path;
  • Notification Content Extension is configured if rich push UI is enabled;
  • Firebase/APNs route is configured correctly;
  • this.reteno.setDeviceToken(token) is called when the app uses external token handling;
  • token is assigned to the Reteno contact;
  • DELIVERED and CLICKED evidence can be verified.

4.1. Ionic Capacitor iOS notification-handler ownership

For Ionic Capacitor iOS, inspect existing notification-response ownership before assuming that Reteno automatically receives foreground and notification-tap callbacks.

Check whether the application uses:

  • @capacitor-firebase/messaging;
  • Capacitor push plugins;
  • custom iOS notification handling;
  • another plugin that registers notification presentation or response handlers.

Capacitor iOS integrations may have a single effective notification-handler path that another plugin already owns.

When the installed Reteno Ionic wrapper exposes the following APIs, verify whether they are required for the current Capacitor iOS integration:

this.reteno.setWillPresentNotificationOptions(...)

and:

this.reteno.setDidReceiveNotificationResponseHandler({
  enabled: true
})

Use these APIs only when:

  • they exist in the installed wrapper version;
  • the current Ionic Capacitor iOS notification architecture requires them;
  • official Reteno documentation or verified project behavior supports their use.

Do not add these calls blindly to Ionic Cordova projects.

Do not replace existing Capacitor/Firebase notification behavior without inspecting ownership first.

When these handlers are required:

  • configure them only after Ionic Platform.ready();
  • preserve existing notification routing;
  • verify foreground notification behavior;
  • verify notification tap behavior;
  • confirm that Reteno receives the interaction required for CLICKED.

Potential failure signature when Reteno does not receive the notification response:

  • push is delivered;
  • notification is visible;
  • user taps the notification;
  • app opens;
  • another Capacitor/Firebase handler receives the response;
  • Reteno CLICKED is missing.

Document in the final report:

  • active runtime;
  • existing iOS notification-handler owner;
  • whether setWillPresentNotificationOptions(...) was required;
  • whether setWillPresentNotificationOptions(...) was configured;
  • whether setDidReceiveNotificationResponseHandler(...) was required;
  • whether setDidReceiveNotificationResponseHandler({ enabled: true }) was configured;
  • CLICKED result.

5. Push opening and CLICKED

After DELIVERED status is available, verify that push interaction is tracked.

The test push notification must be opened in the selected test environment.

If the agent can interact with the device/simulator/emulator:

  1. Open the delivered notification.
  2. Confirm that the app opens.
  3. Continue Reteno-side validation.
  4. Verify CLICKED.

If the agent cannot interact with the environment:

  1. Ask the developer or QA engineer to open the delivered test push manually.
  2. Wait for confirmation.
  3. Continue Reteno-side validation.
  4. Verify CLICKED.

Do not treat inability to tap a notification automatically as an SDK integration failure.

Document it as a local automation limitation or manual fallback.

6. Foreground push handling

If foreground push validation is part of the current integration task, verify the app’s existing foreground push handling.

Do not replace existing foreground push listeners.

Compose Reteno handling with existing Ionic, Cordova, Capacitor, Firebase, or app-level push listeners.

Document:

  • listener used;
  • platform;
  • runtime:
    • Ionic Cordova;
    • Ionic Capacitor;
  • foreground push payload received;
  • app behavior;
  • validation evidence.

7. Custom push data

If custom push data validation is part of the current integration task, verify:

  • expected custom payload fields;
  • actual received payload;
  • foreground behavior;
  • background behavior;
  • terminated-state behavior;
  • app routing or action based on custom data;
  • Reteno-side evidence, if available.

Do not treat Android custom push data behavior as proof of iOS behavior.

Do not treat iOS custom push data behavior as proof of Android behavior.

8. Deeplinks in push payloads

Reteno can deliver deeplinks in push payloads.

In Ionic apps, routing inside the WebView usually requires an app-level deeplink layer.

Supported routing approaches may include:

  • Ionic router;
  • custom URL scheme plugin;
  • Universal Links;
  • Android App Links;
  • Branch.io;
  • Capacitor App plugin;
  • another app-level routing provider.

Do not assume Reteno push delivery automatically navigates to the correct Ionic route.

Expected result:

  • Reteno delivers the push payload;
  • the app-level deeplink router opens the correct route;
  • foreground, background, and terminated-state behavior are validated separately.

Do not treat successful warm-start behavior as proof that cold-start handling works.

Ionic user identification

Use this section when user identification or externalCustomerId validation is part of the current integration task.

Do not validate externalCustomerId unless this check is requested or the integration modifies user identification behavior.

1. Anonymous contact

Before login or registration, SDK initialization should create or update an anonymous contact when the app runs.

Expected result:

  • contact exists in Reteno;
  • contactId is available through Reteno-side evidence, if retrievable;
  • deviceId is available through Reteno-side evidence, if retrievable;
  • platform / OS information is available;
  • externalCustomerId is not required at this stage;
  • mobilePushToken may be assigned if push permission and token setup are complete.

2. Identified user

When the user logs in, signs up, or updates their profile, identify the user through Ionic user information API.

Use:

await this.reteno.setUserAttributes({
  externalUserId: 'USER_ID',
  user: {}
});

Use a stable backend user ID as externalUserId whenever available.

The value may be numeric or non-numeric, as long as it is stable and approved by the product/backend team.

Do not use unstable identifiers such as:

  • device ID;
  • mobile push token;
  • temporary session ID;
  • random UUID generated on the device.

If the application uses email as externalUserId, document it as the selected product identifier, not as an SDK limitation.

Expected result:

  • before login or registration, the contact is anonymous;
  • after login or registration, externalUserId is sent through this.reteno.setUserAttributes(...);
  • Reteno-side externalCustomerId is assigned to the same contact/device;
  • mobilePushToken remains assigned after identification.

3. User attributes

If user attribute validation is part of the current integration task, use this.reteno.setUserAttributes(...) with the approved user attributes.

Example structure:

await this.reteno.setUserAttributes({
  externalUserId: 'USER_ID',
  user: {
    userAttributes: {
      email: '[email protected]',
      firstName: 'John',
      lastName: 'Doe',
      languageCode: 'en',
      timeZone: 'Europe/Kyiv',
      marketId: 'market_1'
    },
    subscriptionKeys: ['news'],
    groupNamesInclude: ['vip'],
    groupNamesExclude: ['inactive']
  }
});

Use valid formats:

  • languageCode: RFC 5646 format;
  • timeZone: TZ database format.

Do not send real personal data in test integrations unless the developer explicitly confirms that the test account is approved.

4. Anonymous user attributes

If anonymous user attributes are part of the current integration task, use:

await this.reteno.setAnonymousUserAttributes({
  firstName: 'Guest',
  lastName: 'User',
  languageCode: 'en',
  timeZone: 'Europe/Kyiv'
});

Do not use anonymous attributes for email or phone.

Use identified user flow with externalUserId when email or phone is involved.

5. Multi-account user attributes

If the app uses multiple Reteno accounts, use the official multi-account user attribute method only when the developer confirms the account suffix and expected account mapping.

Example:

await this.reteno.setMultiAccountUserAttributes({
  externalUserId: 'USER_ID',
  user: {
    userAttributes: {
      firstName: 'John',
      lastName: 'Doe'
    }
  }
});

Document:

  • account suffix;
  • external user ID;
  • which Reteno account received the update;
  • whether the update was verified.

6. Market ID

If marketId is part of the current integration task, verify that the installed Ionic wrapper, Cordova plugin, and native SDK versions support it.

marketId value should contain only:

  • Latin letters;
  • digits;
  • hyphens;
  • underscores.

Maximum length:

64 characters

To clear an existing marketId, pass an empty string.

To keep the existing value unchanged, omit marketId.

Document whether marketId was sent, cleared, omitted, or not requested.

MCP Capability Discovery and Validation

After applying Ionic SDK integration changes, validate the integration through Reteno-side evidence.

Do not mark the integration as complete until all required validation checks pass or a blocker is clearly documented.

MCP capability discovery

Before using Reteno MCP for validation, discover which capabilities are actually available and authorized in the current agent environment.

Verify that Reteno MCP is connected in the same environment where the AI coding agent runs.

For Ionic core mobile push validation, possible capabilities may include:

  • finding a contact by contactId, if available;
  • finding a contact by deviceId, if available;
  • displaying the assigned mobilePushToken;
  • identifying token type: FCM or APNs;
  • creating or selecting a test push notification;
  • sending a test push notification to one approved test contact;
  • checking DELIVERED status;
  • checking CLICKED status after the push notification is opened.

Do not assume that all MCP capabilities are available.

If a required MCP capability is unavailable, use an approved manual fallback, Reteno UI, backend data, SDK logs, device logs, redacted network logs, or mark the step as blocked, manual fallback required, or missing MCP capability.

Do not mark the integration as complete if a required validation step could not be verified.

Reteno MCP and local automation are separate

Reteno MCP validates Reteno-side data and statuses.

Reteno MCP is used for:

  • contact lookup;
  • mobilePushToken verification;
  • token type validation;
  • test push creation and sending when the capability is available and approved;
  • DELIVERED / CLICKED status checks when the capability is available;
  • feature-specific validation when the required MCP capabilities are available.

Local device, simulator, emulator, Ionic CLI, Cordova CLI, Capacitor CLI, Android Studio, Xcode, Gradle, or CocoaPods tooling is used for runtime interaction:

  • building the app;
  • installing the app;
  • running the app;
  • confirming Ionic native platform readiness;
  • confirming Cordova or Capacitor native bridge availability;
  • granting notification permission;
  • opening the delivered test push notification;
  • completing login or registration steps;
  • tapping an In-App message button, if required.

If local automation is unavailable, ask the developer or QA engineer to perform the runtime action manually and continue validation after confirmation.

If Reteno MCP is unavailable, Reteno-side validation must use reliable fallback evidence or be reported as blocked or pending.

Do not treat local automation failure as an SDK integration failure.

Do not treat Reteno MCP failure as a local device automation failure.

Evidence priority

Reteno MCP is the preferred Reteno-side validation path, but MCP itself is not the validation result.

Validation evidence is mandatory.

If MCP is unavailable or a required MCP capability is missing, use reliable fallback evidence when available:

  • Reteno UI;
  • backend data;
  • SDK logs;
  • device logs;
  • redacted network logs;
  • on-device API response;
  • developer / QA confirmation.

When fallback evidence is used:

  • state why MCP was unavailable or insufficient;
  • state which evidence source was used;
  • correlate only through verified identifiers;
  • do not include full push tokens or secrets;
  • report the result as Passed with warnings only if required validation is actually verified;
  • report the result as Blocked or Partial when required validation cannot be verified.

Do not mark a validation step as passed only because code was added.

Validation flow

1. Check selected Reteno mobile app configuration

Verify that the selected Reteno mobile app matches the Ionic target platform.

Expected configuration:

  • Ionic Android: FCM;
  • Ionic iOS with direct APNs: APNs;
  • Ionic iOS with Firebase / FCM: FCM.

Ask the developer or admin to confirm:

  • selected Reteno mobile app;
  • target validation platform:
    • Android;
    • iOS;
    • both;
  • token type configured for the selected app:
    • FCM;
    • APNs;
  • Firebase / FCM setup, if FCM is used;
  • APNs sandbox / production setup, if direct APNs is used;
  • whether the selected Reteno app matches the selected test environment.

If MCP cannot read app-level push configuration, ask the developer or admin to confirm it manually.

Do not change app-level Reteno configuration automatically unless this action is explicitly supported and confirmed by the developer or admin.

2. Create or initialize an anonymous contact

Before login or registration, initialize the SDK and create an anonymous contact.

At this stage, the contact must be anonymous.

To verify that the contact was created, use Reteno MCP, backend data, SDK logs, device logs, Reteno UI, or another reliable evidence source.

Expected result:

  • contactId is available through Reteno-side evidence, if retrievable;
  • deviceId is available through Reteno-side evidence, if retrievable;
  • platform / OS information is available;
  • externalCustomerId is not required at this stage;
  • mobilePushToken may or may not be available, depending on push permission and token setup.

Use contactId as the primary identifier when it is available.

If Reteno MCP supports deviceId lookup, also verify that the same contact can be found by deviceId.

If contactId or deviceId is unavailable, correlate the anonymous contact using available evidence:

  • redacted mobilePushToken;
  • token type;
  • platform;
  • app version / build version;
  • OS version;
  • device model, if available;
  • Reteno contact creation or update timestamp;
  • SDK logs;
  • device logs;
  • Reteno UI;
  • backend data;
  • test push message ID, name, or messageTag.

Do not include full push tokens in the final report.

3. Verify mobilePushToken

After the app is installed, launched, Ionic native platform readiness is reached, SDK is initialized, and push permission / token setup is complete, verify that a mobilePushToken is assigned to the test contact.

Expected result:

  • mobilePushToken is present;
  • token type is correct:
    • Ionic Android: FCM;
    • Ionic iOS with direct APNs: APNs;
    • Ionic iOS with Firebase / FCM: FCM;
  • token belongs to the same contact/device used in the validation run;
  • token matches the selected Reteno mobile app configuration.

Do not include full push token values in the final report.

Use redacted values only when needed for troubleshooting.

If mobilePushToken is missing, check:

  • Ionic native platform readiness reached;
  • Reteno initialized successfully;
  • active runtime is correctly detected:
    • Ionic Cordova;
    • Ionic Capacitor;
  • Firebase / FCM setup is complete, if FCM is used;
  • google-services.json exists and matches the effective Android application ID, if Android is used;
  • GoogleService-Info.plist exists and matches the effective iOS bundle ID, if iOS FCM is used;
  • selected Reteno app token type matches the selected route;
  • Android 13+ notification permission is granted, if Android is used;
  • iOS push permission is granted, if iOS is used;
  • iOS App Group is configured, if iOS is used;
  • Notification Service Extension is configured when required by the selected iOS Reteno feature or validation path;
  • this.reteno.setDeviceToken(token) is called when manual token forwarding is required;
  • existing push plugins are not blocking Reteno token handling.

4. Send a test push

Send a test push only when the required Reteno MCP capability is available and explicitly approved.

Use only one approved test contact.

Do not create or send a broad campaign during validation.

Create and send the test push only to the selected test contact.

Scope the test push explicitly to the current contactId, deviceId, or mobilePushToken, depending on the available MCP capability.

Use a dedicated messageTag, for example:

test

If the MCP permission classifier blocks the push capability, retry only with an explicitly scoped single-contact payload.

If MCP cannot send the test push, ask the developer or admin to send it manually through Reteno UI and provide the message name, ID, or tag for validation.

5. Verify DELIVERED

After the test push is sent, verify delivery.

Expected result:

  • DELIVERED status is available for the test push.

If DELIVERED is not available and ERROR is present:

  1. Check the error code.
  2. Match the error code with Reteno mobile push error documentation.
  3. Explain the likely reason.
  4. Provide troubleshooting steps.

Possible causes may include:

  • missing or invalid mobilePushToken;
  • token type mismatch;
  • incorrect Reteno mobile app configuration;
  • wrong Firebase project;
  • wrong google-services.json;
  • wrong GoogleService-Info.plist;
  • APNs sandbox / production mismatch;
  • missing iOS App Group;
  • missing iOS Notification Service Extension;
  • missing extension Podfile Reteno dependency;
  • Android 13+ notification permission disabled;
  • cordova-plugin-firebasex blocking Reteno FCM callbacks;
  • @capacitor-firebase/messaging or another push plugin owning token/message handling;
  • invalid or outdated token;
  • unsupported test environment;
  • Ionic native platform readiness / SDK initialization did not run.

If no DELIVERED or ERROR status is available, use available MCP capabilities, Reteno UI, backend data, SDK logs, device logs, redacted network logs, or manual confirmation to determine whether validation is blocked or pending.

6. Open the delivered push and verify CLICKED

After DELIVERED status is available, verify that push interaction is tracked.

The delivered test push notification must be opened in the selected test environment.

If the agent can interact with the device/simulator/emulator:

  1. Open the delivered notification.
  2. Confirm that the app opens.
  3. Continue Reteno-side validation.
  4. Verify CLICKED.

If the agent cannot interact with the environment:

  1. Ask the developer or QA engineer to open the delivered test push manually.
  2. Wait for confirmation.
  3. Continue Reteno-side validation.
  4. Verify CLICKED.

Expected result:

  • app opens after the push notification is opened;
  • CLICKED status is available;
  • CLICKED belongs to the same contact/message as DELIVERED.

Do not treat inability to tap a notification automatically as an SDK integration failure.

Document it as a local automation limitation or manual fallback.

7. Validate feature-specific flows

Run feature-specific validation only when the current integration task includes the related feature.

Feature-specific validation may include:

  • custom events;
  • screen tracking;
  • app lifecycle events;
  • In-App messages;
  • mobile-push + In-App;
  • externalCustomerId;
  • deeplinks;
  • custom push data;
  • App Inbox OPENED / UNOPENED statuses, only when App Inbox validation is requested
  • action buttons.

If a feature is not part of the current integration task, report it as:

not requested for this integration

Do not use MVP, extended validation, optional, out of scope, out of MVP scope, included in scope, or selected validation scope wording in the final report.

Local Device, Simulator, Emulator, and Ionic Automation

Reteno MCP and local runtime automation are separate.

Reteno MCP validates Reteno-side data and statuses.

Local runtime automation is used to build, install, launch, and interact with the Ionic application.

Supported local automation methods

For Ionic validation, local automation may include:

  • mobile-mcp;
  • adb;
  • uiautomator;
  • Android Studio tools;
  • Xcode tools;
  • Ionic CLI;
  • Cordova CLI;
  • Capacitor CLI;
  • Gradle;
  • CocoaPods;
  • simulator controls;
  • emulator controls;
  • manual developer / QA interaction.

If mobile-mcp is unavailable but another approved local automation method works, such as adb, uiautomator, Ionic CLI, Cordova CLI, Capacitor CLI, Android Studio, Xcode, or manual interaction, use it and document the method in the final report.

This is not an Ionic SDK integration failure.

Ionic native runtime check

Before runtime validation, verify that the Ionic app is running in a native runtime.

Do not use:

ionic serve
browser preview
PWA runtime

as evidence for native Reteno mobile push validation.

Expected result:

  • app launches as a native Android or iOS app;
  • WebView loads;
  • Ionic native platform readiness is reached;
  • Cordova or Capacitor native bridge is available;
  • Reteno wrapper is available in TypeScript;
  • Reteno initialization is called after native readiness.

If native runtime is unavailable:

  • continue only with non-runtime code/config review;
  • do not mark validation as complete;
  • report runtime validation as blocked;
  • ask the developer to provide a supported native test environment.

Ionic Cordova bridge check

When Ionic Cordova runtime is used, verify:

  • Cordova native bridge is available;
  • deviceready or Ionic Platform.ready() resolves;
  • Cordova plugins are loaded;
  • cordova-plugin-reteno is installed;
  • awesome-cordova-plugins-reteno wrapper is available;
  • this.reteno.init(...) is called after native readiness.

If the Cordova bridge does not become available:

  • do not continue SDK validation;
  • inspect app startup and Cordova plugin loading;
  • ask the developer for runtime logs;
  • report runtime validation as blocked.

Ionic Capacitor bridge check

When Ionic Capacitor runtime is used, verify:

  • Capacitor native bridge is available;
  • Ionic native platform readiness is reached;
  • Cordova-compatible plugin is available through Capacitor compatibility layer;
  • required native configuration was synced or manually verified;
  • this.reteno.init(...) is called after native readiness.

If the Capacitor bridge or Cordova-compatible plugin is unavailable:

  • do not continue SDK validation;
  • inspect Capacitor config and plugin installation;
  • verify whether npx cap sync was approved and run;
  • ask the developer for runtime logs;
  • report runtime validation as blocked.

Android automation

For Android validation, the agent may use:

  • ionic cordova build android;
  • ionic cordova run android;
  • ionic capacitor build android;
  • ionic capacitor run android;
  • Android emulator;
  • physical Android device;
  • adb;
  • uiautomator;
  • Android Studio tools;
  • manual developer / QA interaction.

Runtime actions may include:

  • installing the app;
  • launching the app;
  • confirming Ionic native runtime;
  • confirming Cordova or Capacitor bridge availability;
  • granting notification permission;
  • confirming Android 13+ permission behavior;
  • opening the delivered push notification;
  • confirming app open / navigation after notification tap;
  • collecting device logs.

If the agent cannot open the delivered push automatically, ask the developer or QA engineer to open it manually and continue Reteno-side validation after confirmation.

iOS automation

For iOS validation, the agent may use:

  • ionic cordova build ios;
  • ionic cordova run ios;
  • ionic capacitor build ios;
  • ionic capacitor run ios;
  • Xcode;
  • CocoaPods;
  • iOS simulator, if supported and confirmed by the developer;
  • physical iOS device;
  • manual developer / QA interaction.

Runtime actions may include:

  • installing the app;
  • launching the app;
  • confirming Ionic native runtime;
  • confirming Cordova or Capacitor bridge availability;
  • granting push notification permission;
  • opening the delivered push notification;
  • confirming app open / navigation after notification tap;
  • collecting device logs.

For push validation, physical iOS device is the safest acceptance environment unless the developer confirms that the selected simulator and Xcode runtime support remote notifications and token registration.

If the selected iOS simulator cannot obtain a push token, use it only for build and launch validation and report end-to-end push validation as blocked.

Ionic Cordova platform commands

Ionic Cordova platform commands can rewrite native platform folders.

Do not run these commands without explicit developer approval:

ionic cordova prepare
ionic cordova platform rm android
ionic cordova platform add android
ionic cordova platform rm ios
ionic cordova platform add ios
cordova prepare
cordova clean

If a command is required, document:

  • why it is required;
  • which platform it affects;
  • whether platforms/ folders are committed;
  • whether manual native changes may be overwritten;
  • whether the developer approved the action.

Ionic Capacitor platform commands

Capacitor commands can update or rewrite native project files.

Do not run these commands without explicit developer approval:

npx cap sync
npx cap sync android
npx cap sync ios
npx cap copy
npx cap copy android
npx cap copy ios

If a command is required, document:

  • why it is required;
  • which platform it affects;
  • whether native android/ or ios/ folders are committed;
  • whether manual native changes may be overwritten;
  • whether the developer approved the action.

Manual fallback

Use manual fallback when:

  • local automation is unavailable;
  • GUI interaction is required;
  • push notification must be opened manually;
  • login or registration is required;
  • In-App message must be clicked manually;
  • Cordova platform regeneration requires approval;
  • Capacitor sync/copy requires approval;
  • signing, provisioning, Apple Developer account access, or Firebase dashboard access is required;
  • simulator/emulator/device access is unavailable to the agent.

When manual fallback is used, the final report must document:

  • what action was requested;
  • who completed the action;
  • when it was completed, if known;
  • what evidence was provided;
  • which validation step resumed after the manual action.

Validation Requirements

The agent must validate every Reteno SDK feature that it integrates, modifies, or is explicitly asked to verify.

Do not treat feature-specific validation as optional when the feature is part of the current integration task.

Core mobile push validation

When mobile push integration is included, the following checks are required:

  • Ionic runtime type detected;
  • native runtime confirmed;
  • SDK initialization after Ionic native platform readiness;
  • contact creation;
  • notification permission request;
  • mobilePushToken assignment;
  • token type validation;
  • test push sending;
  • DELIVERED status;
  • push notification opening;
  • CLICKED status;
  • final report.

Do not mark the integration as complete until core mobile push validation passes or a blocker is clearly documented.

Platform-specific token expectations

Expected token type depends on platform and selected Reteno app configuration:

PlatformExpected token type
Ionic AndroidFCM
Ionic iOS with direct APNsAPNs
Ionic iOS with Firebase / FCMFCM

The token assigned to the contact must match the token type configured for the selected Reteno mobile app.

Ionic Cordova Android validation success criteria

For Ionic Cordova Android validation, success requires:

  • Ionic app root detected;
  • Ionic framework type detected;
  • active runtime confirmed as Ionic Cordova;
  • cordova-plugin-reteno installed or confirmed;
  • awesome-cordova-plugins-reteno installed or confirmed;
  • wrapper major compatible with @awesome-cordova-plugins/core major;
  • for Ionic Angular, Reteno wrapper imported from awesome-cordova-plugins-reteno/ngx;
  • for Ionic Angular, Reteno wrapper registered in Angular providers;
  • cordova-android version is 12.0.0 or higher;
  • google-services.json present and matching the effective Android application ID;
  • Google Services Gradle plugin applied;
  • Android 13+ notification permission flow configured when required;
  • Firebasex / push-handler conflict checked;
  • app builds and runs on the selected Android test environment;
  • Ionic native platform readiness is reached;
  • Cordova bridge is available;
  • SDK initializes after native readiness;
  • contact is created or found;
  • mobilePushToken is assigned;
  • token type is FCM;
  • test push is sent to one approved test contact when the capability is available and approved;
  • delivery evidence is verified;
  • click / interaction evidence is verified after opening the notification;
  • push handling method names used for validation are documented when foreground push, custom push data, notification click, or action buttons are part of the current integration task;
  • no READ push status is used; App Inbox OPENED / UNOPENED is reported only when App Inbox validation is explicitly requested;
  • final report documents any fallback evidence or warnings.

Ionic Capacitor Android validation success criteria

For Ionic Capacitor Android validation, success requires:

  • Ionic app root detected;
  • Ionic framework type detected;
  • active runtime confirmed as Ionic Capacitor;
  • cordova-plugin-reteno installed or confirmed through Capacitor compatibility;
  • awesome-cordova-plugins-reteno installed or confirmed;
  • wrapper major compatible with @awesome-cordova-plugins/core major;
  • for Ionic Angular, Reteno wrapper is imported from awesome-cordova-plugins-reteno/ngx;
  • for Ionic Angular, Reteno wrapper is registered in Angular providers;
  • Capacitor config checked;
  • android/app/google-services.json present and matching the effective Android application ID;
  • Google Services Gradle plugin applied or verified manually;
  • npx cap sync android approved and completed when required;
  • Android 13+ notification permission flow configured when required;
  • Capacitor Firebase Messaging / push-handler conflict checked;
  • app builds and runs on the selected Android test environment;
  • Ionic native platform readiness is reached;
  • Capacitor bridge is available;
  • SDK initializes after native readiness;
  • contact is created or found;
  • mobilePushToken is assigned;
  • token type is FCM;
  • test push is sent to one approved test contact when the capability is available and approved;
  • delivery evidence is verified;
  • click / interaction evidence is verified after opening the notification;
  • push handling method names used for validation are documented when foreground push, custom push data, notification click, or action buttons are part of the current integration task;
  • no READ push status is used; App Inbox OPENED / UNOPENED is reported only when App Inbox validation is explicitly requested;
  • final report documents any fallback evidence or warnings.

Ionic Cordova iOS validation success criteria

For Ionic Cordova iOS validation, success requires:

  • Ionic app root detected;

  • Ionic framework type detected;

  • active runtime confirmed as Ionic Cordova;

  • cordova-plugin-reteno installed or confirmed;

  • awesome-cordova-plugins-reteno installed or confirmed;

  • wrapper major compatible with @awesome-cordova-plugins/core major;

  • for Ionic Angular, Reteno wrapper is imported from awesome-cordova-plugins-reteno/ngx;

  • for Ionic Angular, Reteno wrapper is registered in Angular providers;

  • iOS deployment target is 15.0 or higher;

  • Xcode 15.0 or higher is available;

  • Swift 5.7 or higher is supported;

  • selected IOS_DEVICE_TOKEN_HANDLING_MODE is documented;

  • Push Notifications capability configured when required;

  • App Group configured in the required format;

  • Notification Service Extension configured when required;

  • extension target includes the required Reteno dependency through the active iOS dependency manager when extension functionality is required;

  • active iOS dependency manager is detected and documented;

  • CocoaPods-specific requirements are applied only when CocoaPods is used;

  • Swift Package Manager requirements are applied when the project uses SPM;

  • extension target Reteno pod version is pinned and matches the installed plugin plugin.xml Reteno pod spec;

  • app builds and runs on the selected iOS test environment;

  • Ionic native platform readiness is reached;

  • Cordova bridge is available;

  • SDK initializes after native readiness;

  • contact is created or found;

  • mobilePushToken is assigned;

  • token type is APNs or FCM, depending on selected route;

  • test push is sent to one approved test contact when the capability is available and approved;

  • delivery evidence is verified;

  • click / interaction evidence is verified after opening the notification;

  • push handling method names used for validation are documented when foreground push, custom push data, notification click, or action buttons are part of the current integration task;

  • no READ push status is used; App Inbox OPENED / UNOPENED is reported only when App Inbox validation is explicitly requested;

  • final report documents any fallback evidence or warnings.

Ionic Capacitor iOS validation success criteria

For Ionic Capacitor iOS validation, success requires:

  • Ionic app root detected;
  • Ionic framework type detected;
  • active runtime confirmed as Ionic Capacitor;
  • cordova-plugin-reteno installed or confirmed through Capacitor compatibility;
  • awesome-cordova-plugins-reteno installed or confirmed;
  • wrapper major compatible with @awesome-cordova-plugins/core major;
  • for Ionic Angular, Reteno wrapper is imported from awesome-cordova-plugins-reteno/ngx;
  • for Ionic Angular, Reteno wrapper is registered in Angular providers;
  • Capacitor config checked;
  • iOS deployment target is 15.0 or higher;
  • Xcode 15.0 or higher is available;
  • Swift 5.7 or higher is supported;
  • selected IOS_DEVICE_TOKEN_HANDLING_MODE is documented;
  • npx cap sync ios approved and completed when required;
  • Push Notifications capability configured when required;
  • App Group configured in the required format;
  • Notification Service Extension configured manually or confirmed when required;
  • active iOS dependency manager is detected;
  • required extension targets include Reteno through the active CocoaPods or Swift Package Manager path;
  • extension Reteno dependency version matches the native Reteno iOS SDK version required by the selected plugin;
  • app builds and runs on the selected iOS test environment;
  • Ionic native platform readiness is reached;
  • Capacitor bridge is available;
  • SDK initializes after native readiness;
  • contact is created or found;
  • mobilePushToken is assigned;
  • token type is APNs or FCM, depending on selected route;
  • test push is sent to one approved test contact when the capability is available and approved;
  • delivery evidence is verified;
  • click / interaction evidence is verified after opening the notification;
  • push handling method names used for validation are documented when foreground push, custom push data, notification click, or action buttons are part of the current integration task;
  • no READ push status is used; App Inbox OPENED / UNOPENED is reported only when App Inbox validation is explicitly requested;
  • final report documents any fallback evidence or warnings.

Feature-specific validation

Run feature-specific validation only when the feature is part of the current integration task.

When both Android and iOS are included in the current integration task, distinguish between:

Resulting Reteno state verified

and:

Platform-specific SDK method execution independently verified

A shared Reteno contact may contain:

  • Android mobile-push channel;
  • iOS mobile-push channel;
  • one shared externalCustomerId;
  • shared user attributes.

That shared contact-level state may verify that the final Reteno contact state is correct.

However, do not represent shared contact-level state as proof that a specific SDK method was independently executed successfully on each platform unless the evidence can distinguish those platform-specific calls.

For requested feature validation, preserve separate evidence for Android and iOS when the execution itself is platform-specific.

This applies to features such as:

  • custom events;
  • user identification / externalCustomerId;
  • user attributes;
  • deeplinks;
  • custom push data;
  • foreground push handling;
  • background push handling;
  • terminated-state handling;
  • action buttons;
  • In-App interactions.

For example, if a custom event is independently observed only from Android:

Android: Passed
iOS: Not independently verified

Do not report:

Android + iOS: Passed

only because both platforms are associated with the same Reteno contact.

When platform-specific backend evidence is unavailable:

  • use platform-specific SDK logs when reliable;
  • use platform-specific device logs;
  • use approved on-device network/API evidence;
  • use developer / QA confirmation for the specific platform when appropriate;
  • clearly state the remaining attribution limitation.

Do not downgrade a verified resulting Reteno state unnecessarily.

Instead, report separately:

  • resulting Reteno state;
  • Android SDK execution evidence;
  • iOS SDK execution evidence.

Feature-specific validation may include:

  • custom events;
  • user identification / externalCustomerId;
  • user attributes;
  • anonymous user attributes;
  • multi-account user attributes;
  • screen tracking;
  • app lifecycle events;
  • deeplinks;
  • custom push data;
  • In-App messages;
  • mobile-push + In-App;
  • action buttons;
  • App Inbox OPENED / UNOPENED statuses, only when App Inbox validation is requested.

Do not use READ as an Ionic SDK push status.

For mobile push validation, use only:

DELIVERED
CLICKED

If App Inbox validation is explicitly requested, use App Inbox statuses:

OPENED
UNOPENED

Document App Inbox validation separately from mobile push validation.

If a feature was not part of the current integration task, report it as:

not requested for this integration

If a feature was part of the current integration task but could not be validated, report it as one of the following:

blocked
manual fallback required
missing MCP capability
unavailable test environment
unavailable Reteno UI / admin setup

Evidence rules

The final report must state how each result was verified.

Valid evidence may include:

  • Reteno MCP result;
  • Reteno UI confirmation;
  • backend data;
  • SDK logs;
  • device logs;
  • redacted network logs;
  • on-device API response;
  • screenshot or screen recording;
  • developer / QA confirmation.

Evidence collected on one platform must not be treated as evidence for another platform.

Android result does not validate iOS.

iOS result does not validate Android.

Ionic Cordova result does not validate Ionic Capacitor.

Ionic Capacitor result does not validate Ionic Cordova.

Complete vs Partial report

Use Complete only when all required validation checks for the current integration task pass.

Use Partial when any required build, run, runtime interaction, Reteno-side validation, contact lookup, contact correlation, token verification, test push, DELIVERED, CLICKED, or feature-specific validation step was skipped, blocked, or not verified.

Use Passed with warnings only when required validation passes but non-blocking warnings remain.

Use Blocked when the integration cannot continue because of missing credentials, missing Reteno MCP, unavailable native runtime, unavailable test environment, unavailable Firebase/APNs setup, Cordova platform regeneration approval, Capacitor sync approval, Firebasex conflict, Capacitor Firebase Messaging conflict, signing issues, or required manual action that has not been completed.

Use Failed when the integration was attempted and a required validation check failed with evidence.

Do not mark a validation step as passed only because code was added.

Ionic Troubleshooting

If validation fails, identify the failed step and troubleshoot before escalating.

Do not stop immediately after a failed validation check.

Check the likely cause, document the result, retry safe fixes, and continue with the remaining validation steps where possible.

Ionic project type is unclear

If the Ionic project type cannot be classified, inspect:

  • ionic.config.json;
  • package.json;
  • src/;
  • Angular / React / Vue files;
  • config.xml;
  • capacitor.config.ts;
  • capacitor.config.json;
  • platforms/;
  • plugins/;
  • android/;
  • ios/;
  • Cordova scripts;
  • Capacitor scripts;
  • installed plugin list;
  • repository instructions.

Do not run Ionic, Cordova, or Capacitor platform commands until the project type and active runtime are confirmed.

If still unclear, ask the developer whether the project is:

  • Ionic Cordova;
  • Ionic Capacitor;
  • both Cordova and Capacitor indicators with one active runtime;
  • browser/PWA-only Ionic;
  • pure Cordova;
  • non-Ionic project.

Active runtime is unclear

If both Cordova and Capacitor indicators are present:

  • stop before installing plugins;
  • stop before editing native files;
  • stop before running prepare/sync/copy commands;
  • ask the developer to confirm the active runtime.

Do not assume Cordova runtime only because config.xml exists.

Do not assume Capacitor runtime only because capacitor.config.* exists.

Native runtime is unavailable

If the app can only be run through:

ionic serve
browser preview
PWA runtime

do not attempt native Reteno mobile push validation.

Expected limitations:

  • native plugin may be unavailable;
  • push token may not be assigned;
  • Reteno native SDK may not initialize;
  • DELIVERED / CLICKED validation cannot pass.

Resolution:

  • ask the developer to provide Ionic Cordova or Ionic Capacitor native runtime;
  • continue only with code/config review;
  • report runtime validation as blocked.

Wrapper version mismatch

If awesome-cordova-plugins-reteno and @awesome-cordova-plugins/core have incompatible major versions:

  • do not upgrade automatically;
  • document the mismatch;
  • ask the developer whether wrapper/core version alignment can be changed;
  • install the Reteno wrapper major matching the existing core major when possible.

Do not upgrade @awesome-cordova-plugins/core across major versions without explicit approval.

this.reteno is undefined

If the Ionic Reteno wrapper is undefined:

  • verify awesome-cordova-plugins-reteno is installed;
  • verify @awesome-cordova-plugins/core is installed;
  • verify wrapper import path;
  • verify provider/service registration for Ionic Angular;
  • verify plugin installation;
  • verify native runtime is used, not browser preview;
  • verify native platform readiness before plugin usage.

Do not continue Reteno validation until the wrapper and native plugin bridge are available.

Ionic native platform readiness does not happen

If Ionic native readiness does not resolve:

  • SDK initialization cannot be validated;
  • Cordova or Capacitor native bridge may not be ready;
  • plugins may not be loaded;
  • app startup may be broken.

Check:

  • app entry point;
  • Ionic bootstrap;
  • Platform.ready() usage;
  • Cordova script inclusion, if Cordova runtime is used;
  • Capacitor runtime setup, if Capacitor runtime is used;
  • runtime console logs;
  • plugin installation state.

Do not initialize Reteno before Ionic native platform readiness.

SDK initialization is missing or duplicated

If SDK initialization does not work, check:

  • whether this.reteno.init(...) is called;
  • whether it is called after Ionic native platform readiness;
  • whether it is called only once;
  • whether SDK access key is available;
  • whether plugin variable, config.xml, or capacitor.config.* is correct;
  • whether initialization is delayed by app startup, authentication, or routing logic.

Do not duplicate this.reteno.init(...).

Do not initialize Reteno before native bridge is ready.

Ionic Cordova platform ownership is unclear

If platforms/ folders exist, determine whether they are generated artifacts or committed source.

If generated:

  • prefer changes in config.xml, plugin variables, hooks, or source files;
  • avoid direct manual edits under platforms/;
  • run ionic cordova prepare only if approved.

If committed and manually maintained:

  • inspect native changes carefully;
  • preserve existing native configuration;
  • ask before regenerating platforms.

Do not run ionic cordova platform rm/add or ionic cordova prepare until platform ownership is clear.

Ionic Capacitor native ownership is unclear

If native android/ or ios/ folders exist, determine whether they are generated artifacts or committed source.

If generated:

  • prefer changes in capacitor.config.*, plugin setup, or source files;
  • run npx cap sync only if approved.

If committed and manually maintained:

  • inspect native changes carefully;
  • preserve existing native configuration;
  • ask before running sync/copy.

Do not run npx cap sync or npx cap copy until native ownership is clear.

Plugin variable changed but native config did not update

If SDK_ACCESS_KEY or IOS_DEVICE_TOKEN_HANDLING_MODE was changed but native config did not update:

For Ionic Cordova:

  • confirm whether Cordova plugin variables were changed after plugin installation;
  • confirm whether ionic cordova prepare is required;
  • confirm whether plugin reinstall is required;
  • ask for developer approval before running platform regeneration or plugin reinstall.

For Ionic Capacitor:

  • confirm whether capacitor.config.* was updated;
  • confirm whether npx cap sync is required;
  • confirm whether manual native config update is required;
  • ask for developer approval before running sync or manual native changes.

Do not repeatedly edit generated files if the actual issue is stale native output.

Android build fails

If Android build fails, check:

  • Ionic CLI version;
  • active runtime: Cordova or Capacitor;
  • Cordova CLI version, if Cordova runtime is used;
  • cordova-android version, if Cordova runtime is used;
  • Capacitor version, if Capacitor runtime is used;
  • cordova-plugin-reteno version;
  • awesome-cordova-plugins-reteno version;
  • Android Gradle plugin version;
  • Gradle wrapper version;
  • Java / JDK version used by Gradle;
  • compileSdk;
  • targetSdk;
  • minSdk;
  • Android namespace configuration;
  • exact dependency requiring a higher compile SDK, if applicable;
  • Gradle files;
  • Java / Kotlin compatibility;
  • google-services.json;
  • Google Services Gradle plugin;
  • Firebase dependencies;
  • Android package name / applicationId;
  • duplicate Firebase Messaging service definitions;
  • cordova-plugin-firebasex;
  • @capacitor-firebase/messaging;
  • generated or committed native Android project.

Do not repeat the same failed action without a new hypothesis.

If the issue requires local environment access or cannot be resolved safely by the agent, ask the developer to run the app through Ionic CLI, Android Studio, Cordova CLI, Capacitor CLI, or Gradle and provide:

  • exact error message;
  • Ionic CLI logs;
  • Cordova or Capacitor CLI logs;
  • Gradle logs;
  • emulator or device details;
  • reproduction steps.

cordova-android is below 12.0.0

If Ionic Cordova Android uses cordova-android below 12.0.0:

  • do not proceed as if Android setup is valid;
  • report the platform version blocker;
  • ask the developer whether upgrading cordova-android is approved.

Do not upgrade cordova-android automatically.

Treat the upgrade as a product/build compatibility decision.

Android mobilePushToken is missing

If the Android contact exists but mobilePushToken is missing, check:

  • Ionic native platform readiness reached;
  • Reteno initialized successfully;
  • active runtime is correctly detected;
  • cordova-android version is 12.0.0 or higher, if Cordova runtime is used;
  • google-services.json exists;
  • google-services.json matches the effective Android application ID;
  • Google Services Gradle plugin is applied;
  • Reteno app is configured for Android / FCM;
  • Firebase server-side configuration is completed in Reteno;
  • notification permission is granted on Android 13+;
  • cordova-plugin-firebasex is not blocking Reteno FCM callbacks;
  • @capacitor-firebase/messaging or another push plugin is not owning token/message handling unexpectedly;
  • app was launched after integration changes;
  • network is available;
  • token assignment has had time to sync.

Firebasex or Capacitor Firebase Messaging conflict

If cordova-plugin-firebasex, @capacitor-firebase/messaging, or another push plugin is installed and Reteno FCM callbacks do not work:

  • inspect AndroidManifest merged services;
  • inspect generated or committed native Android project;
  • check whether another plugin registers FirebaseMessagingService;
  • check whether Reteno callbacks receive FCM token;
  • ask an Android/Ionic SME to confirm the correct integration path.

Do not remove existing push plugins automatically.

If an existing push plugin is required by the app, preserve it and document the limitation or required follow-up.

Android push does not arrive after force-stop

Do not treat missing FCM delivery after an Android force-stop as a Reteno SDK integration defect by itself.

Android may block normal FCM delivery after the application is explicitly force-stopped by the user or through system settings until the app is launched again.

Distinguish between:

  • application normally running;
  • application in foreground;
  • application normally backgrounded;
  • application process terminated by the OS;
  • application explicitly force-stopped.

For core Reteno push validation, do not use an explicitly force-stopped application as the normal background-delivery acceptance case.

If a test push does not arrive after force-stop:

  1. confirm that the application was explicitly force-stopped;
  2. launch the application again;
  3. confirm that Reteno initialization and token registration complete;
  4. background the application normally;
  5. resend the test push;
  6. verify visible notification delivery;
  7. verify DELIVERED;
  8. open the notification and verify CLICKED.

If push delivery works after normal relaunch/backgrounding, do not report the force-stop behavior as a Reteno SDK defect.

Document the tested Android app state in the final report when force-stop behavior affected validation.

iOS build fails

If iOS build fails, check:

  • Ionic CLI version;
  • active runtime: Cordova or Capacitor;
  • Cordova CLI / cordova-ios version, if Cordova runtime is used;
  • Capacitor version, if Capacitor runtime is used;
  • cordova-plugin-reteno version;
  • awesome-cordova-plugins-reteno version;
  • iOS deployment target;
  • Xcode version;
  • Swift version;
  • config.xml;
  • capacitor.config.*;
  • active iOS dependency manager:
    • CocoaPods;
    • Swift Package Manager;
    • mixed;
  • Podfile, Podfile.lock, CocoaPods installation, pod install, and .xcworkspace, only when CocoaPods is used;
  • Package.swift, Package.resolved, and Xcode Swift Package dependencies, when Swift Package Manager is used;
  • resolved native Reteno iOS SDK version;
  • Notification Service Extension;
  • Notification Content Extension;
  • extension Reteno dependency through the active dependency manager, when required;
  • App Groups;
  • signing and provisioning;
  • GoogleService-Info.plist, if Firebase / FCM is used;
  • APNs / FCM setup.

Do not treat a missing Podfile as an error when the Ionic Capacitor iOS project intentionally uses Swift Package Manager.

Do not add CocoaPods to an SPM-based project only because an older runbook example uses a Podfile.

Use the dependency manager already owned by the current native project unless the developer explicitly approves a migration.

If the issue requires local environment access or cannot be resolved safely by the agent, ask the developer to run the app through Ionic CLI, Xcode, Cordova CLI, Capacitor CLI, or CocoaPods and provide:

  • exact error message;
  • Xcode logs;
  • CocoaPods logs;
  • simulator or device details;
  • reproduction steps.

CocoaPods cannot resolve Reteno

Use this troubleshooting path only when the active iOS project uses CocoaPods.

If the project uses Swift Package Manager instead, do not run CocoaPods commands.

For SPM-based projects, inspect:

  • Package.swift, when present;
  • Package.resolved;
  • Xcode package dependencies;
  • selected Reteno package version;
  • package product linked to the main application target;
  • package product linked to the Notification Service Extension, when required.

Do not create a Podfile only to follow this troubleshooting section.

If CocoaPods cannot find compatible versions for pod Reteno:

  • run pod install --repo-update only when developer approves;
  • run it from the active iOS native project directory;
  • or ask the developer to run the appropriate Ionic iOS build command with repo update when applicable.

If CocoaPods requires a higher minimum deployment target:

  • confirm current deployment target;
  • ask developer to approve iOS 15.0+;
  • update config only after approval.

iOS mobilePushToken is missing

If the iOS contact exists but mobilePushToken is missing, check:

  • Ionic native platform readiness reached;
  • Reteno initialized successfully;
  • iOS deployment target is 15.0 or higher;
  • selected IOS_DEVICE_TOKEN_HANDLING_MODE;
  • push permission is granted;
  • App Group is configured;
  • Notification Service Extension is configured when required by the selected Reteno feature or validation path;
  • extension Podfile includes Reteno when required;
  • Firebase / FCM setup is correct, if iOS uses Firebase / FCM;
  • GoogleService-Info.plist is added to the app target, if Firebase / FCM is used;
  • this.reteno.setDeviceToken(token) is called when another SDK/plugin owns token retrieval;
  • APNs sandbox / production route is correct;
  • selected Reteno app token type matches the selected route.

Do not treat a missing Notification Service Extension as proof that core mobile push validation has failed.

Core mobile push validation may still pass when all required core checks are independently verified:

  • contact exists;
  • mobilePushToken is present;
  • token type is correct;
  • test push is delivered;
  • DELIVERED is verified;
  • the notification is opened;
  • CLICKED is verified.

Treat Notification Service Extension as required when the selected Reteno feature or push behavior depends on extension processing.

If core push passes without the extension:

  • report core mobile push validation separately;
  • report the missing Notification Service Extension as a warning or incomplete extension-specific setup;
  • do not claim that extension-dependent or rich notification behavior was validated.

iOS DELIVERED is missing

If iOS test push is sent but DELIVERED is missing, check:

  • whether selected route is FCM or direct APNs;
  • whether token type matches selected Reteno app;
  • whether APNs sandbox / production routing is correct;
  • whether App Group name is exactly group.<main-app-bundle-id>.reteno-local-storage;
  • whether App Group is applied to both main app and Notification Service Extension;
  • whether Notification Service Extension builds and runs;
  • whether extension target has the required Reteno pod;
  • whether Firebase APNs credentials are valid, if Firebase / FCM is used;
  • whether this.reteno.setDeviceToken(token) is required and called.

Do not assume SDK integration is wrong until token routing and push-provider configuration are confirmed.

CLICKED is missing

If DELIVERED is available but CLICKED is missing, check:

  • delivered notification was actually opened;
  • agent or developer opened the correct notification;
  • app opened after notification interaction;
  • Ionic WebView was resumed;
  • custom notification response handler is configured only when required;
  • app-level routing did not swallow the interaction;
  • terminated-state handling is tested separately from background state;
  • Reteno MCP can retrieve click status;
  • fallback evidence exists through SDK logs, device logs, Reteno UI, or backend data.

If the agent cannot open the notification automatically, request manual opening and continue validation after confirmation.

Deeplink or custom push data does not work

If deeplink or custom push data validation is part of the current integration task, test separately:

  • foreground state;
  • background state;
  • terminated state;
  • custom URL scheme;
  • Universal Link or Android App Link;
  • Ionic router navigation;
  • Branch.io, if used;
  • Capacitor App plugin, if used;
  • actual WebView route;
  • actual destination screen.

Check:

  • Ionic router configuration;
  • Cordova deeplink plugin, if used;
  • Capacitor App plugin, if used;
  • WebView navigation;
  • Reteno push payload;
  • custom push payload callback;
  • duplicate navigation handling.

Do not treat successful warm-start behavior as proof that cold-start handling works.

In-App message does not appear

If In-App message validation is part of the current integration task and the message does not appear, check:

  • SDK is initialized;
  • Ionic native platform readiness reached;
  • contact exists;
  • target contact is eligible;
  • segment rules match;
  • frequency limits;
  • trigger event or app-open trigger;
  • In-App message is active and published in the selected non-production environment;
  • selected Reteno app/environment is correct;
  • MCP capability exists or Reteno UI fallback is available;
  • app session is active;
  • logs show In-App fetch/display evidence.

Do not publish or modify In-App messages without explicit developer or admin approval.

Screen tracking does not work

In Ionic apps, native automatic screen tracking is usually not meaningful because the UI runs inside a WebView.

Use manual screen tracking from the Ionic router when screen analytics are part of the current integration task.

Expected result:

  • screen name is logged from the actual Ionic route;
  • event is assigned to the correct contact;
  • event can be verified through Reteno MCP, Reteno UI, backend data, SDK logs, or device logs.

Reteno MCP status lookup is unavailable or returns an error

If MCP status lookup capabilities are unavailable, return empty results, or return an error, do not assume validation failed immediately.

Use approved fallback evidence when available:

  • Reteno UI;
  • backend data;
  • SDK logs;
  • device logs;
  • on-device API responses;
  • redacted network logs;
  • developer / QA confirmation.

When fallback evidence is used:

  • document which MCP capability was unavailable or failed;
  • document which fallback evidence was used;
  • correlate evidence only through available and verified identifiers;
  • do not include full push tokens or secrets;
  • report the result as Passed with warnings if required validation passed through fallback evidence;
  • report the result as Blocked or Partial if no reliable fallback evidence is available.

Final Report Format

The agent must return a concise structured final report after every Ionic integration run.

Do not use a long field-by-field report by default.

Use:

  • Core report for every run;
  • Runtime-specific section only for the active Ionic runtime;
  • Android section only if Android validation was part of the current integration task;
  • iOS section only if iOS validation was part of the current integration task;
  • Feature-specific section only for features requested in the current integration task.

Validation result is mandatory.

Reteno MCP is the preferred Reteno-side validation path, but MCP itself is not the validation result.

If MCP is unavailable or a required MCP capability is missing, use reliable fallback evidence when available:

  • Reteno UI;
  • backend data;
  • SDK logs;
  • device logs;
  • redacted network logs;
  • on-device API response;
  • developer / QA confirmation.

Do not mark validation as passed unless the result is verified through at least one reliable evidence source.

Core report

FieldResult
Report typeComplete / Partial
Overall statusPassed / Passed with warnings / Blocked / Failed
Repository / project
Branch / commit
Initial worktree stateClean / Dirty / Unknown
Application root
Ionic frameworkAngular / React / Vue / Unknown
Ionic runtimeCordova / Capacitor / Both indicators / Browser-only / Unknown
Target validation platformAndroid / iOS / Both
cordova-plugin-reteno version
awesome-cordova-plugins-reteno version
@awesome-cordova-plugins/core version
Wrapper/core major compatibilityPassed / Failed / Not checked
Wrapper peer-dependency compatibilityPassed / Warning / Failed / Not checked
Wrapper peer-dependency mismatchNone / See warnings
Peer-dependency installation workaroundNone / --legacy-peer-deps / Version change / Other
Reteno wrapper package integrityPassed / Broken published package / Workaround used / Not checked
Reteno /ngx entry point verifiedYes / No / Not applicable
Wrapper workaroundNone / Version pin / Vendored build / Package patch / Other
Wrapper workaround removal follow-upRequired / Not required / Not applicable
Initialization resultPassed / Failed / Not run
Application bootstrap / render resultPassed / Failed / Not run
Reteno runtime initialization reachedYes / No / Not verified
Reteno startup causality isolationNot required / Performed / Not possible
Startup blocker classificationReteno-related / Pre-existing or unrelated / Not determined / Not applicable
Ionic native platform readinessPassed / Failed / Not run
Native bridge availableCordova / Capacitor / Not available / Not run
Build/run resultPassed / Failed / Not run
Pre-existing / collateral compatibility fixes requiredYes / No
Compatibility fixes caused directly by Reteno SDK codeYes / No / Not determined / Not applicable
Separate product QA / maintenance follow-up requiredYes / No
Core push validationPassed / Failed / Blocked / Not run
Evidence sourcesMCP / Reteno UI / backend / SDK logs / device logs / manual confirmation
Sandbox configuration usedYes / No
Merge readinessReady / Not ready / Not applicable
Blockers
Warnings
Changed files
Recommended next steps

Runtime section, if applicable

Include one of these runtime summaries.

Ionic Cordova runtime

Report:

  • config.xml status;
  • installed Cordova platforms;
  • platform folders committed: Yes / No / Unknown;
  • ionic cordova prepare run: Yes / No;
  • ionic cordova platform rm/add run: Yes / No;
  • Cordova plugin variables changed: Yes / No;
  • native platform regeneration approval: Approved / Not approved / Not required.

Ionic Capacitor runtime

Report:

  • capacitor.config.ts / capacitor.config.json status;
  • installed Capacitor platforms;
  • native folders committed: Yes / No / Unknown;
  • npx cap sync run: Yes / No;
  • npx cap copy run: Yes / No;
  • Cordova preferences configured in Capacitor config: Yes / No;
  • manual native changes required: Yes / No;
  • Capacitor sync approval: Approved / Not approved / Not required.
  • manual native changes survive npx cap sync: Yes / No / Not verified / Not applicable;
  • post-sync fix required: Yes / No;
  • post-sync mechanism, if required:
    • project script;
    • Capacitor configuration;
    • package patch;
    • manual reapply;
    • other;
  • post-sync fix re-verified after the last sync: Yes / No / Not applicable.
  • final manual native change occurred before or after the last relevant npx cap sync;
  • last relevant npx cap sync occurred after the final manual native change: Yes / No / Not applicable;
  • native durability verdict:
    • verified after final sync;
    • not verified after final native change;
    • not applicable;
  • durability verification limitation, if any.
  • required native Reteno / Firebase configuration tracked or reproducible: Yes / No / Not verified;
  • required integration state exists only in gitignored native folders: Yes / No;
  • tracked reproduction mechanism:
    • Capacitor configuration;
    • project script;
    • package patch;
    • committed native source;
    • other;
    • none;
  • native integration reproducibility verified: Yes / No / Not verified;
  • manual reapply required after regeneration: Yes / No;

Android section, if applicable

Include this section only when Android validation was part of the current integration task.

Report:

  • Android package name / application ID;
  • active runtime:
    • Ionic Cordova;
    • Ionic Capacitor;
  • cordova-android version, if Cordova runtime is used;
  • whether cordova-android is 12.0.0 or higher, if applicable;
  • Firebase config source;
  • whether google-services.json exists and matches the effective Android application ID;
  • Google Services Gradle plugin status;
  • whether cordova-plugin-firebasex was detected;
  • whether @capacitor-firebase/messaging was detected;
  • whether @capacitor/push-notifications was detected;
  • other Cordova / Capacitor / legacy FCM push plugins detected, if any;
  • competing MESSAGING_EVENT service package/class, if any;
  • push-handler conflict result:
    • not detected;
    • detected and verified;
    • detected and blocked pending SME review;
  • merged MESSAGING_EVENT service ownership;
  • Reteno FirebaseMessagingService active for notification processing: Yes / No / Not verified;
  • competing Firebase Messaging service removed or disabled: Yes / No / Not required;
  • competing push plugin retained for token retrieval only: Yes / No / Not applicable;
  • visible system-tray notification verified: Yes / No / Not verified;
  • Android build-toolchain changes required: Yes / No;
  • compileSdk before / after, if changed;
  • targetSdk before / after, if changed;
  • Android Gradle Plugin before / after, if changed;
  • Gradle before / after, if changed;
  • JDK used for validation;
  • whether build-toolchain changes were Reteno-required, framework-required, or pre-existing project compatibility fixes;
  • Android 13+ notification permission result;
  • token type expected: FCM;
  • token type verified: FCM / other / not verified;
  • mobilePushToken result: present / missing / not verified;
  • test push result;
  • DELIVERED result;
  • CLICKED result;
  • Android-specific fallback evidence, if used.

iOS section, if applicable

Include this section only when iOS validation was part of the current integration task.

Report:

  • iOS bundle ID;
  • active runtime:
    • Ionic Cordova;
    • Ionic Capacitor;
  • native Reteno dependency source;
  • resolved native Reteno iOS SDK version;
  • iOS deployment target;
  • whether iOS deployment target is 15.0 or higher;
  • selected push route:
    • direct APNs;
    • Firebase / FCM;
  • selected IOS_DEVICE_TOKEN_HANDLING_MODE:
    • manual;
    • automatic;
  • whether this.reteno.setDeviceToken(...) was required;
  • whether this.reteno.setDeviceToken(...) was implemented;
  • extension Reteno dependency status;
  • extension dependency manager:
    • CocoaPods;
    • Swift Package Manager;
    • other;
    • not applicable;
  • FCM token owner:
    • Reteno internal Firebase bridge;
    • @capacitor-firebase/messaging;
    • Firebasex;
    • application code;
    • other;
  • FCM token forwarding path:
    • automatic;
    • this.reteno.setDeviceToken(...);
    • other;
  • duplicate token forwarding detected: Yes / No / Not verified;
  • Firebase config source, if Firebase / FCM is used;
  • whether GoogleService-Info.plist exists and matches the effective iOS bundle ID;
  • App Group name;
  • whether App Group uses the required format;
  • Notification Service Extension status;
  • Notification Content Extension status, if applicable;
  • Capacitor iOS notification response handler configuration used: Yes / No / Not required;
  • setWillPresentNotificationOptions(...) used: Yes / No / Not available / Not required;
  • setDidReceiveNotificationResponseHandler(...) used: Yes / No / Not available / Not required;
  • active iOS dependency manager:
    • CocoaPods;
    • Swift Package Manager;
    • mixed;
    • unknown;
  • resolved main-app Reteno iOS SDK version;
  • extension Reteno dependency mechanism:
    • CocoaPods;
    • Swift Package Manager;
    • not applicable;
  • whether extension Reteno version matches the main-app / plugin-required Reteno iOS SDK version;
  • token type expected:
    • APNs;
    • FCM;
  • token type verified:
    • APNs;
    • FCM;
    • other;
    • not verified;
  • mobilePushToken result:
    • present;
    • missing;
    • not verified;
  • test push result;
  • DELIVERED result;
  • CLICKED result;
  • iOS-specific fallback evidence, if used.

Feature-specific section, if applicable

Include this section only for features requested in the current integration task.

For each requested feature, report:

#### <Feature name>

- Requested: Yes
- Implemented: Yes / No / Not applicable
- Validated: Passed / Failed / Blocked / Not run
- Evidence source:
- Blocker or warning:

When both Android and iOS are included in the current integration task, use platform-specific feature evidence:

#### <Feature name>

- Requested: Yes
- Implemented: Yes / No / Not applicable
- Android validation: Passed / Failed / Blocked / Not run / Not independently verified
- Android evidence source:
- iOS validation: Passed / Failed / Blocked / Not run / Not independently verified
- iOS evidence source:
- Reteno-side resulting state: Passed / Failed / Not verified / Not applicable
- Platform attribution limitation:
- Blocker or warning:

Do not use evidence from one platform to mark the other platform as passed.

If shared Reteno contact state confirms the final data but cannot distinguish the originating platform-specific SDK calls, report that distinction explicitly.

Feature-specific checks may include:

  • custom event;
  • screen tracking;
  • app lifecycle events;
  • user identification / externalCustomerId;
  • deeplink;
  • custom push data;
  • foreground push handling;
  • background push handling;
  • terminated-state push handling;
  • action buttons;
  • In-App message;
  • mobile-push + In-App flow.

If a feature was not part of the current integration task, report it as:

not requested for this integration

Additional Ionic report details

Do not use:

MVP
extended validation
optional
out of scope
out of MVP scope
included in scope
selected validation scope

When Ionic Angular is used, report:

  • Reteno wrapper import source:
    • awesome-cordova-plugins-reteno/ngx;
    • package root;
    • not applicable;
  • Angular provider registration:
    • NgModule providers;
    • standalone bootstrap providers;
    • missing;
    • not applicable;
  • whether constructor injection succeeded;
  • whether NullInjectorError occurred.

When iOS extension targets are configured, report:

  • installed cordova-plugin-reteno/plugin.xml Reteno pod spec;
  • extension target Reteno pod version;
  • whether extension pod version is pinned;
  • whether extension pod version matches plugin plugin.xml.

When push handling, custom push data, or action buttons are validated, report:

  • getInitialNotification() result, if used;
  • foreground push listener method used;
  • notification clicked listener method used;
  • action button listener method used;
  • notification action handler method used;
  • app state tested:
    • foreground;
    • background;
    • terminated / cold start.

When App Inbox validation is requested, report:

  • App Inbox status:
    • OPENED;
    • UNOPENED;
  • evidence source.

Do not report READ as a push status.

Report rules

Use Complete only when all required validation checks for the current integration task pass.

Use Partial when any required build, run, runtime interaction, Reteno-side validation, contact correlation, token verification, test push, DELIVERED, CLICKED, or requested feature-specific validation step was skipped, blocked, or not verified.

Use Passed only when all required validation checks pass.

Use Passed with warnings only when required validation passes but non-blocking warnings remain, such as:

  • manual fallback was used;
  • MCP was unavailable but reliable fallback evidence verified the result;
  • non-required feature validation was not requested;
  • sandbox configuration was used intentionally and documented;
  • runtime-specific setup required manual verification.

Use Blocked when the integration cannot continue because of missing credentials, missing Reteno access, unavailable native runtime, unavailable test environment, unavailable Firebase/APNs setup, Cordova platform regeneration approval, Capacitor sync approval, Firebasex conflict, Capacitor Firebase Messaging conflict, signing issue, or required manual action that has not been completed.

Use Failed when the integration was attempted and a required validation check failed with evidence.

Do not require requestId or any other implementation-specific MCP response field in the final report.

Do not include secrets, SDK access keys, Firebase server credentials, APNs private keys, certificates, service account data, or full push token values in the final report.

Use redacted values for sensitive identifiers when needed.

If a secret was exposed in tool output, do not repeat the secret value in the final report.

Report only:

  • what type of secret was exposed;
  • where it was exposed: logs, terminal output, tool output, screenshot, or prompt;
  • whether rotation is recommended;
  • which provider/dashboard should be used for rotation.

Use:

Secret exposure detected: Yes
Secret rotation recommended: Yes

Do not include the exposed value itself.