Skip to main content
RapidDev - Software Development Agency
flutterflow-integrationsCustom Action (Dart)

AnyDesk

You cannot embed a live AnyDesk remote-desktop session inside a FlutterFlow app. The practical integration is a Custom Action using the url_launcher Dart package that deep-links to the installed AnyDesk client via the anydesk: URI scheme. For account management, AnyDesk's REST API requires HMAC-signed requests — route those through a Firebase Cloud Function, never client-side Dart.

What you'll learn

  • Why you cannot embed a remote-desktop session inside a FlutterFlow app and what to do instead
  • How to add the url_launcher dependency to a Custom Action in FlutterFlow
  • How to write a Dart Custom Action that launches anydesk:<ID> with an installed-check and download fallback
  • How to wire the deep-link action to a button using the Action Flow Editor
  • Why AnyDesk's REST API requires a backend proxy and how to set one up with Firebase Cloud Functions
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate14 min read30 minutesDevOps & ToolsLast updated July 2026RapidDev Engineering Team
TL;DR

You cannot embed a live AnyDesk remote-desktop session inside a FlutterFlow app. The practical integration is a Custom Action using the url_launcher Dart package that deep-links to the installed AnyDesk client via the anydesk: URI scheme. For account management, AnyDesk's REST API requires HMAC-signed requests — route those through a Firebase Cloud Function, never client-side Dart.

Quick facts about this guide
FactValue
ToolAnyDesk
CategoryDevOps & Tools
MethodCustom Action (Dart)
DifficultyIntermediate
Time required30 minutes
Last updatedJuly 2026

What 'Connecting FlutterFlow to AnyDesk' Actually Means

When founders search for 'FlutterFlow AnyDesk integration,' they usually want to add a 'Start Remote Support' button to their app — tapping it should open a remote-desktop session. The honest answer is that this is only achievable as a handoff: your FlutterFlow app launches the AnyDesk client already installed on the user's device via the anydesk: URI scheme, much like how a phone app might open a maps URL in Google Maps. There is no Flutter widget, WebView, or iframe path that renders a live remote-desktop session inside a FlutterFlow app.

The practical result is still useful: a button in your support app that reads a pre-configured or user-entered AnyDesk ID and launches the session in the native AnyDesk client. This covers the vast majority of real use-cases — technicians or support teams handling remote access directly from a mobile or web app dashboard.

Beyond the deep link, AnyDesk provides a REST API at https://v1.api.anydesk.com/ for account-level management: listing clients, browsing the address book, and pulling session history. This API is gated to paid business licenses (AnyDesk Solo starts around $15/month — verify current pricing at anydesk.com/pricing) and requires every request to be signed with an HMAC-SHA1 signature computed from your License ID and API password. Because that signing secret must never ship inside a compiled Flutter app, any real-time account queries must go through a Firebase Cloud Function or Supabase Edge Function, with FlutterFlow calling your function rather than AnyDesk directly.

Integration method

Custom Action (Dart)

FlutterFlow integrates with AnyDesk primarily through a Custom Action that uses the url_launcher pub.dev package to open the AnyDesk client app via a deep link (anydesk:<ID>). This hands off control to the native AnyDesk application rather than embedding any session inside your FlutterFlow app. For the rare need to query AnyDesk account or session data, a Firebase Cloud Function handles the HMAC-signed API requests and FlutterFlow calls that function — keeping the signing secret off the client.

Prerequisites

  • A FlutterFlow project (Free plan or higher)
  • AnyDesk installed on the test device (the deep link targets the native client)
  • For the management API: an AnyDesk business license with REST API access enabled
  • For the management API: a Firebase project with Cloud Functions enabled (Blaze plan required for outbound HTTP calls)
  • The AnyDesk ID(s) you want to launch stored in your app's data source or entered by the user

Step-by-step guide

1

Set realistic expectations — what this integration can and cannot do

Before writing a line of code, make sure your team understands the boundary. FlutterFlow compiles your app into a Flutter client running on the user's device — it is not a server and it cannot embed a remote-desktop session. AnyDesk does not publish a Flutter SDK, a WebView-embeddable widget, or any way to render a live session inside a third-party app UI. Trying to load anydesk.com in a FlutterFlow WebView widget will not give you a working remote-desktop session — it will show a marketing page or redirect to a download. What you CAN do: launch the AnyDesk native client that is already installed on the device, passing an AnyDesk ID in the anydesk: URI scheme (e.g. anydesk:123456789). The user's AnyDesk app opens in the foreground and connects to that ID. This is a handoff, not an embed — and it is genuinely useful for support workflows. For account/session management data (client list, session history, address book), the AnyDesk REST API at https://v1.api.anydesk.com/ is available on business licenses, but it requires per-request HMAC-SHA1 signing with a secret that must never ship inside your compiled app. That means the API must be called from a backend (Firebase Cloud Function or Supabase Edge Function), not from FlutterFlow directly. Decide right now which scenario you need: (A) deep-link handoff only, or (B) deep link plus management API via a backend proxy. Most teams need only (A). Once you have clarity on the scope, proceed to the next step.

Pro tip: If your use-case is purely 'tap a button, open AnyDesk on the same device,' you can finish this integration in under 30 minutes with just the url_launcher Custom Action. The backend proxy is optional and only needed if you want to read or write AnyDesk account data inside the app.

Expected result: You have a clear picture of which path you are building: deep-link only, or deep-link plus management API via a Cloud Function proxy.

2

Add the url_launcher Custom Action and its dependency

In your FlutterFlow project, click Custom Code in the left navigation panel. Click the + Add button and choose Action from the dropdown. Name the action something descriptive like LaunchAnyDeskSession. In the action editor, scroll down to the Dependencies field and type url_launcher — select the latest stable version from the pub.dev dropdown (at the time of writing, url_launcher 6.x is current; FlutterFlow will show available versions). Click Save after adding the dependency. Now open the Code tab of the action and paste the Dart code shown below. The action accepts one argument: anyDeskId (a String), which is the numeric AnyDesk ID you want to connect to. The code checks whether the anydesk: scheme can be launched on this device (important for iOS — see the tip below), and falls back to opening the AnyDesk download page if the app is not installed. After pasting the code, scroll up in the action editor to define the argument: click + Add Argument → name it anyDeskId → type String → mark it as required. Save the action. FlutterFlow will add the url_launcher package to your project's dependencies automatically — you do not need to run flutter pub get manually. Important: Custom Actions do not execute in FlutterFlow's web builder Run mode. The url_launcher deep link will only fire when you test on a real physical device (use Test on Device or compile an APK/IPA). Do not try to validate this step in the browser preview.

launch_any_desk_session.dart
1import 'package:url_launcher/url_launcher.dart';
2
3Future launchAnyDeskSession(String anyDeskId) async {
4 final anyDeskUri = Uri.parse('anydesk:$anyDeskId');
5 final fallbackUri = Uri.parse('https://anydesk.com/en/downloads');
6
7 if (await canLaunchUrl(anyDeskUri)) {
8 await launchUrl(anyDeskUri, mode: LaunchMode.externalApplication);
9 } else {
10 // AnyDesk not installed — open the download page
11 if (await canLaunchUrl(fallbackUri)) {
12 await launchUrl(fallbackUri, mode: LaunchMode.externalApplication);
13 }
14 }
15}

Pro tip: On iOS, canLaunchUrl only works for custom URL schemes that are declared in LSApplicationQueriesSchemes in your app's Info.plist. In FlutterFlow, go to Settings & Integrations → App Settings → iOS → iOS Info.plist → Custom URL Schemes and add anydesk. Without this, canLaunchUrl will always return false on iOS even if AnyDesk is installed.

Expected result: The LaunchAnyDeskSession action appears in your Custom Code list with a green checkmark and the url_launcher dependency listed under it.

3

Wire the Custom Action to a button via the Action Flow Editor

Now connect the deep-link action to a UI element in your FlutterFlow canvas. If you do not already have a screen for this feature, create one — for example, a 'Remote Support' screen with a Text widget showing the AnyDesk ID and a Button widget labelled 'Launch AnyDesk.' Click the Button widget on the canvas to select it, then open the Actions panel on the right side of the editor (the lightning bolt icon). Click + Add Action. In the action chooser dialog, scroll to the Custom section and select LaunchAnyDeskSession. You will see a field for the anyDeskId argument. For the ID value, you have two options: (1) If the AnyDesk ID is stored in a Firestore document or Supabase row for this client, use a backend query to fetch it and bind the Text widget + the action argument to the same database field. (2) If the user types the ID manually, add a TextField to the screen, store its value in a Page State variable, and bind the action argument to that variable. Set the argument binding to whichever data source applies, then click Confirm. The button is now wired. To test, compile the app to a physical Android or iOS device using FlutterFlow's Test on Device option. Tap the button — if AnyDesk is installed, it should open immediately; if not, the browser opens the AnyDesk download page.

Pro tip: If you want the button to be disabled when no AnyDesk ID is available, wrap the button in a Conditional Visibility widget or use the button's Disable property and bind it to an isEmpty check on the Page State variable holding the ID.

Expected result: Tapping the button on a physical device opens the AnyDesk app (or the download page if AnyDesk is not installed). The button is correctly bound to a dynamic AnyDesk ID from your data source.

4

(Optional) Set up a Firebase Cloud Function proxy for AnyDesk REST API calls

If your use-case requires reading AnyDesk account data — session history, address book, connected clients — inside the FlutterFlow app, you need the AnyDesk REST API. Every request to https://v1.api.anydesk.com/ must include a timestamp and an HMAC-SHA1 signature computed from your License ID and API password. Because the API password is a secret that must never ship in a compiled Flutter app, you cannot call the AnyDesk API directly from a FlutterFlow API Call or a Custom Action. You must route these calls through a backend function. In your Firebase console, go to Functions and create a new Cloud Function (Node.js). The function accepts the endpoint path and any query parameters from your FlutterFlow app, computes the HMAC signature server-side using your AnyDesk License ID and API password stored as environment variables (via firebase functions:config:set or Secret Manager), and forwards the signed request to the AnyDesk API. The response is passed back to FlutterFlow as plain JSON. Once deployed, note your Cloud Function's HTTPS URL. Back in FlutterFlow, go to API Calls in the left nav → + Add → Create API Group. Name it AnyDeskProxy, set the base URL to your Cloud Function URL. Add an API Call inside the group (e.g., GET /sessions) and define any parameters your function accepts. Under Response & Test, paste a sample JSON response from AnyDesk's documentation and click Generate JSON Paths to let FlutterFlow extract the fields automatically. Bind those fields to your UI widgets as usual. This pattern keeps your AnyDesk API password completely off the client. If you would rather skip building the Cloud Function yourself, RapidDev's team builds FlutterFlow integrations like this every week — free scoping call at rapidevelopers.com/contact.

index.js
1// Firebase Cloud Function (Node.js) — AnyDesk REST API proxy
2const functions = require('firebase-functions');
3const crypto = require('crypto');
4const fetch = require('node-fetch');
5
6exports.anyDeskProxy = functions.https.onRequest(async (req, res) => {
7 res.set('Access-Control-Allow-Origin', '*');
8 if (req.method === 'OPTIONS') { res.status(204).send(''); return; }
9
10 const licenseId = process.env.ANYDESK_LICENSE_ID;
11 const apiPassword = process.env.ANYDESK_API_PASSWORD;
12 const endpoint = req.query.endpoint || '/clients';
13
14 const timestamp = Math.floor(Date.now() / 1000).toString();
15 const signBase = `${licenseId}:${timestamp}:${apiPassword}`;
16 const signature = crypto
17 .createHash('sha1')
18 .update(signBase)
19 .digest('hex');
20
21 const apiUrl = `https://v1.api.anydesk.com${endpoint}`;
22 const response = await fetch(apiUrl, {
23 headers: {
24 'Authorization': `AnyDesk ${licenseId}:${timestamp}:${signature}`,
25 'Content-Type': 'application/json'
26 }
27 });
28
29 const data = await response.json();
30 res.status(response.status).json(data);
31});

Pro tip: Store ANYDESK_LICENSE_ID and ANYDESK_API_PASSWORD in Firebase environment config or Secret Manager — never hardcode them in the function source. Verify the exact HMAC signing specification in AnyDesk's current API documentation, as the signing scheme may differ by API version.

Expected result: Your Cloud Function is deployed and returns AnyDesk account data when called from a browser or Postman. The FlutterFlow API Group targeting the function URL fetches and displays the data in a ListView on a test device.

Common use cases

Remote IT support portal with one-tap session launch

A field-service app shows a list of client machines with their AnyDesk IDs pre-populated from your backend. A technician taps a card, and the Custom Action fires the anydesk: deep link, opening a session immediately. The FlutterFlow app handles the directory and the handoff; AnyDesk handles the actual remote-desktop session.

FlutterFlow Prompt

Build a support dashboard screen that shows a list of clients with their AnyDesk IDs. Tapping a client launches the AnyDesk app on the technician's device connected to that ID. Show a fallback prompt to download AnyDesk if it is not installed.

Copy this prompt to try it in FlutterFlow

Session history viewer for business accounts

An ops app pulls recent AnyDesk session logs from a Firebase Cloud Function that signs and calls the AnyDesk REST API. The FlutterFlow app displays session durations, connected clients, and timestamps in a list — giving managers visibility into remote support activity without logging into the AnyDesk web portal.

FlutterFlow Prompt

Create a screen that lists the last 30 AnyDesk sessions from my business account, showing start time, duration, and client name. Fetch the data from a backend function since the AnyDesk API needs HMAC signing.

Copy this prompt to try it in FlutterFlow

Customer self-service remote-access button

A SaaS company embeds a 'Share My Screen' button in their FlutterFlow customer app. Tapping it launches AnyDesk with the customer's device ID pre-filled so a support agent can connect. The session ID is generated and stored by the backend; the app reads it and passes it straight into the deep link.

FlutterFlow Prompt

Add a 'Get Help' screen that shows the user's AnyDesk ID (fetched from backend) and a 'Start Session' button that opens the AnyDesk app to that ID. If AnyDesk is not installed, open the AnyDesk download page in the browser.

Copy this prompt to try it in FlutterFlow

Troubleshooting

Tapping the button does nothing — the AnyDesk app never opens

Cause: Custom Actions (and url_launcher deep links) do not execute in FlutterFlow's web builder Run mode or browser preview. The anydesk: URI scheme also requires AnyDesk to be installed on the device.

Solution: Test on a physical device using FlutterFlow's Test on Device option or compile an APK. Confirm AnyDesk is installed on the test device. On iOS, also check that you added anydesk to LSApplicationQueriesSchemes in Settings & Integrations → App Settings → iOS → iOS Info.plist.

canLaunchUrl always returns false on iOS even though AnyDesk is installed

Cause: iOS requires custom URL schemes to be whitelisted in LSApplicationQueriesSchemes before canLaunchUrl can detect them. Without this, iOS returns false regardless of whether the app is present.

Solution: In FlutterFlow, navigate to Settings & Integrations → App Settings → iOS → iOS Info.plist → Custom URL Schemes and add anydesk. Rebuild the app and re-test on device.

AnyDesk REST API returns 401 Unauthorized from the Cloud Function

Cause: The HMAC signature is either computed incorrectly (wrong string format or hash algorithm) or the License ID / API password environment variables are not set on the deployed function.

Solution: Verify the signing string format in the current AnyDesk API documentation — it is typically licenseId:timestamp:apiPassword hashed with SHA1. Confirm the environment variables are configured via firebase functions:config:set or Secret Manager and that the function was redeployed after setting them.

XMLHttpRequest error when calling the Cloud Function from a web-published FlutterFlow app

Cause: The browser enforces CORS for web builds. If the Cloud Function does not return the Access-Control-Allow-Origin header, browser requests are blocked even though mobile builds work fine.

Solution: Ensure your Cloud Function sets res.set('Access-Control-Allow-Origin', '*') and handles OPTIONS preflight requests with a 204 response, as shown in the proxy code snippet above. Mobile native builds are not affected by CORS.

Best practices

  • Never attempt to embed an AnyDesk session in a WebView or iframe — it will not work and will confuse users with a marketing page instead of a session.
  • Store AnyDesk IDs in your backend database rather than hardcoding them in the app, so they can be updated without a new app release.
  • On iOS, always declare the anydesk URL scheme in LSApplicationQueriesSchemes and provide a graceful fallback to the download page for users who do not have AnyDesk installed.
  • Keep the AnyDesk API password exclusively in your Cloud Function environment variables — never in client Dart, App Constants, or FlutterFlow API Call headers.
  • Use a read-only or scoped AnyDesk API credential in your Cloud Function if AnyDesk's plan supports token scoping — minimize the blast radius of a credential leak.
  • Test the url_launcher Custom Action on both Android and iOS physical devices before shipping; behavior in the web builder preview is not representative of real device behavior.
  • Add a loading indicator and an error state to the button action flow, so users get clear feedback if the deep link or Cloud Function call takes longer than expected.

Alternatives

Frequently asked questions

Can I show a live remote-desktop session inside my FlutterFlow app?

No. FlutterFlow does not have a widget, plugin, or WebView path that renders a live AnyDesk remote-desktop session. The AnyDesk protocol requires a native client application. The only integration available is launching the AnyDesk client app via a deep link, which opens the session outside your FlutterFlow app in the native AnyDesk application.

Does this deep-link approach work on web builds of my FlutterFlow app?

Partially. The url_launcher package can open the anydesk: URI in a browser, but the browser needs to know how to handle the scheme — on desktop, it will prompt to open the AnyDesk desktop client if installed. On mobile web, behavior varies. For a reliable experience, publish your app as a native iOS or Android app rather than a web build for this specific feature.

Which AnyDesk pricing plan gives access to the REST API?

The AnyDesk REST API is gated to paid business licenses, with the exact plan requirements varying — verify the current tiers at anydesk.com/pricing. The Solo plan ($15/month at time of writing) may not include API access. The deep-link feature has no API requirement and works with any AnyDesk plan, including the free tier for personal use.

Why can't I just put the AnyDesk API password in a FlutterFlow App Constant?

FlutterFlow App Constants are compiled into the app binary. Anyone with the APK or IPA can extract them with basic reverse-engineering tools. The AnyDesk API password combined with your License ID gives full read/write access to your AnyDesk account data. Always keep it in a Firebase Cloud Function environment variable or Secret Manager and have the app call your function, not the AnyDesk API directly.

Can I use this integration in FlutterFlow's web builder preview?

The deep-link Custom Action will not fire in FlutterFlow's browser-based Run mode — Custom Actions only execute on real device builds. Use FlutterFlow's Test on Device feature, or compile and install an APK/IPA on a physical device. The API Call portion (if using the Cloud Function proxy) can be tested in the Response & Test tab of the API Calls panel within the builder.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Integrations are where projects stall

We wire FlutterFlow integrations like this one every week — auth, webhooks, edge cases included. Fixed-price builds from $13K, delivered in 6–10 weeks.

Talk to an integration engineer

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.