Skip to content

Feat: remote functions#3097

Open
chrismclarke wants to merge 13 commits intomasterfrom
feat/remote-functions
Open

Feat: remote functions#3097
chrismclarke wants to merge 13 commits intomasterfrom
feat/remote-functions

Conversation

@chrismclarke
Copy link
Member

@chrismclarke chrismclarke commented Aug 18, 2025

PR Checklist

  • PR title descriptive (can be used in release notes)

Description

Adds support for remote-functions feature that allows triggering remote cloud functions.
Includes firebase cloud function integration with support for AppCheck

Git Issues

Relates to #3015

Review Notes

  1. A rapidproUserData function has been created and deployed to firebase functions on the debug deployment. This function is secured with appCheck.

  2. Update debug deployment firebase config to include appCheck site key and functions region. Enable remote functions with firebase provider

config.firebase = {
  // ... existing code

  // Enable appCheck with site key generated from google cloud console (debug project)
  appCheck:{recaptchaEnterpriseSiteKey:'6LdLYakrAAAAAGW1eU7MAPdsMUIwxYk4y3LqxiVO'},
  
  // Configure firebase functions region
  // NOTE - not strictly required (default is us-central1), but would need change if project deploys functions to different region
  functions:{
   region: 'us-central1'
  }
}
config.remote_functions={
  provider:'firebase'
}
  1. Recompile the deployment
yarn workflow deployment set debug
  1. Run the app
yarn start
  1. Go to the remote-functions debug at http://localhost:4200/remote-functions

  2. Attempt to call the function rapidproUserData, passing a rapidpro_uuid parameter to retrieve from rapidpro. A test contact has been created with uuid 700c4bd4-c7e5-4414-9ff2-2b1ff2571947

image

The function will fail due to appCheck blocking from unknown source.

  1. Add local device to AppCheck debug whitelist

By default AppCheck will run in debug mode, generating a device token locally that can be added to list of whitelisted apps in the firebase console.
Look for message that resembles:

App Check debug token: fb3f032e-890f-4b61-8eae-5c1ed8994e5c. You will need to add it to your app's App Check settings in the Firebase console for it to work.

Add the listed ID to the whitelisted debug token within the firebase console App Check -> Apps page

image
  1. Refresh the page to see available token

  2. Call remote function and view response

Dev Notes

This PR only adds backend infrastructure and debug page for calling remote functions. I'm sure we will want to expose to the full authoring system via actions at some point, however as time is somewhat limited at the moment I'd suggest we first try to directly integrate with the plh-parent-group service so that the service exposes it's own action that handles calling the function and displaying results.

Given the potential sensitivity of the rapidpro contact data it is recommended not to persist to the dynamicDB caching system, and instead only show data directly in the page following function trigger (online-only functionality).

See additional notes in README for feature

Follow-up Tasks

  • Test appCheck integration when deployed to live debug site (should work without need for any additional token configuration) - The associated recaptcha enterprise project has whitelisted idems-debug.web.app so functions should trigger from that website (and fail when testing on corresponding firebase .web.app site)
  • Integrate with parenting group system to retrieve parent rapidpro data via the corresponding remote function
  • Configure appcheck and deploy functions for target deployments
  • Configure and test appCheck to work with Android and IOS apps (done from firebase console - however not done on debug project as we don't deploy as an app)

Screenshots/Videos

Example Setup - creating a new reCaptcha Enterprise key to use with AppCheck on web
image

@chrismclarke chrismclarke marked this pull request as ready for review August 21, 2025 22:55
@chrismclarke chrismclarke requested a review from jfmcquade August 21, 2025 22:56
@chrismclarke chrismclarke changed the title Feat/remote functions Feat: remote functions Aug 21, 2025
@chrismclarke
Copy link
Member Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant new feature for remote functions, including Firebase integration with AppCheck. The overall structure is well-thought-out, leveraging modern Angular features like signals and standalone components as recommended by the style guide. I've identified a critical issue with a hardcoded key and a few high-severity issues related to encapsulation that should be addressed. Additionally, there are several medium-severity suggestions to improve code quality, maintainability, and the usability of the new debug page. Great work on setting up this new capability!

@chrismclarke
Copy link
Member Author

/gemini summary

@gemini-code-assist
Copy link
Contributor

Summary of Changes

This pull request introduces a new remote-functions feature, enabling the application to trigger cloud functions, specifically integrating with Firebase Cloud Functions. It includes robust security measures via Firebase AppCheck. The current implementation provides the foundational backend infrastructure and a dedicated debug page for testing these remote function calls.

Highlights

  • Remote Functionality: Implemented core support for triggering remote cloud functions, laying the groundwork for future integrations.
  • Firebase Integration: Established integration with Firebase Cloud Functions as the primary provider for remote function execution.
  • Enhanced Security with AppCheck: Integrated Firebase AppCheck to ensure secure invocation of cloud functions, including configuration for web, Android, and iOS platforms.
  • Configurability: Introduced new deployment configuration options for Firebase AppCheck site keys and function regions, and enabled the remote_functions provider.
  • Developer Debugging Tool: Added a new debug page (/remote-functions) to facilitate local testing and interaction with remote functions, allowing input of function names and parameters, and displaying responses.
  • Dependency Management: Updated package.json to include necessary @capacitor-firebase/app-check and @capacitor-firebase/functions dependencies.
  • Action Type Extension: Extended FlowTypes.ActionType to include remote_function, preparing for future authoring system integration.
Changelog
  • package.json
    • Added @capacitor-firebase/app-check and @capacitor-firebase/functions dependencies.
  • packages/data-models/deployment.model.ts
    • Updated DEPLOYMENT_CONFIG_VERSION to 20250818.0.
    • Introduced appCheck configuration (with recaptchaEnterpriseSiteKey) and functions configuration (with region) under the firebase property in IDeploymentRuntimeConfig.
    • Added remote_functions configuration (with provider: "firebase") to IDeploymentRuntimeConfig and DEPLOYMENT_RUNTIME_CONFIG_DEFAULTS.
  • packages/data-models/flowTypes.ts
    • Added "remote_function" to the FlowTypes.ActionType enum.
  • packages/scripts/src/tasks/providers/appData.ts
    • Modified generateRuntimeConfig to include remote_functions in the destructuring of deploymentConfig.
  • src/app/app-routing.module.ts
    • Added a new route for /remote-functions to dynamically load the REMOTE_FUNCTION_ROUTES.
  • src/app/feature/remote-function/README.md
    • New file providing an overview, setup instructions for the Firebase provider (including App Check for web, Android, and iOS), testing notes, TODOs, and troubleshooting information for remote functions.
  • src/app/feature/remote-function/index.ts
    • New file defining REMOTE_FUNCTION_ROUTES for the debug page.
    • Exports initialiseRemoteFunctions to register the remote_function action.
    • Exports provideRemoteFunctions for environment providers.
  • src/app/feature/remote-function/pages/debug/remote-function-debug.page.html
    • New file containing the HTML template for the remote function debug page, including input fields for function name and parameters, a run button, response display, and AppCheck token status.
  • src/app/feature/remote-function/pages/debug/remote-function-debug.page.ts
    • New file implementing the component logic for the debug page, managing function name, parameters, triggering functions, and displaying responses, along with Firebase AppCheck token display.
  • src/app/feature/remote-function/providers/base.ts
    • New file defining RemoteFunctionInvokeParams, RemoteFunctionErrorResponse, and RemoteFunctionProviderBase as a base class for remote function providers.
  • src/app/feature/remote-function/providers/firebase.ts
    • New file implementing FirebaseFunctionProvider for Firebase cloud functions, including AppCheck integration (web and native) and function invocation logic.
  • src/app/feature/remote-function/providers/index.ts
    • New file exporting getFunctionProvider to select the appropriate remote function provider based on configuration.
  • src/app/feature/remote-function/remote-function.actions.ts
    • New file defining RemoteFunctionActionFactory to handle remote_function actions, including a placeholder run action.
  • src/app/feature/remote-function/remote-function.service.ts
    • New file defining the core service for remote functions, managing the selected provider and its initialization.
  • src/app/feature/remote-function/remote-function.types.ts
    • New file defining IRemoteFunctionProvider type.
Activity
  • The author, chrismclarke, initiated a review of the pull request.
  • gemini-code-assist[bot] identified a critical issue where the reCAPTCHA Enterprise site key was hardcoded in FirebaseFunctionProvider. This issue was subsequently resolved by the author.
  • gemini-code-assist[bot] suggested making the config getter in RemoteFunctionService public for better encapsulation. The author opted to keep it private for now, noting its use is limited to the debug page.
  • gemini-code-assist[bot] recommended making appCheckToken and appCheckTokenError signals in FirebaseFunctionProvider public. The author chose to keep them private, stating they are only accessed from the debug page.
  • gemini-code-assist[bot] pointed out that accessing private members using bracket notation in RemoteFunctionDebugPage violates encapsulation. The author decided to keep them private for the time being, as they are only used by the debug page.
  • gemini-code-assist[bot] noted that the run action in RemoteFunctionActionFactory was registered but unimplemented. This issue was resolved by the author.
  • gemini-code-assist[bot] suggested moving inline styles from remote-function-debug.page.html to a dedicated stylesheet for better maintainability.
  • gemini-code-assist[bot] identified a redundant @if check in remote-function-debug.page.html. This was resolved by the author.
  • gemini-code-assist[bot] recommended initializing targetFunctionName in RemoteFunctionDebugPage as an empty string instead of a hardcoded value. This was resolved by the author.
  • gemini-code-assist[bot] suggested removing hardcoded test data from ngOnInit in RemoteFunctionDebugPage for a cleaner debug state. This was resolved by the author.
  • The author, chrismclarke, requested a summary of the pull request.

@chrismclarke
Copy link
Member Author

@jfmcquade - just to check if this needs to be on your radar for upcoming releases or not?

@jfmcquade
Copy link
Collaborator

@jfmcquade - just to check if this needs to be on your radar for upcoming releases or not?

Thanks for the prompt. I believe this has been deprioritised for now as it is no longer required in the current round of pending releases – @ChrisMarsh82 can you confirm?

But would still obviously be good to review and keep things moving, I'll add to my to-do list (likely will get to it next week)

@chrismclarke chrismclarke force-pushed the feat/remote-functions branch 2 times, most recently from 27200a7 to 795ec1a Compare November 12, 2025 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scripts Work on backend scripts and devops

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants