Using Doppler in a Flutter/Dart project?

Anyone used Doppler in a Flutter/Dart project? I’m not sure how to do it- as such I’m not sure if this is a feature request or a call for help. Thanks in advance!

Also, does Doppler ever serve secrets on a per request basis- like not at compile/build time but in-line with a request that requires a secret, it would fetch the Doppler secret first and then complete the request with the secret.

Hey Eric and welcome to the Doppler community!

While we don’t yet have a Swift SDK, you use a API to either download all the secrets for a config or request a single secret.

Are you able to describe your use case and how you’re wanting to use Doppler in your application?

Cheers,
Ryan

After some planning, I think it is actually two use cases:

  1. For non-sensitive secrets, like environment flags and publishable keys, I would like to inject secrets at compile/build time into a dart/flutter project. I don’t see a Dart/Flutter example in the docs and it isn’t obvious to me how I would do it.
  2. For sensitive secrets, I was imagining doing the above, or storing them server side and requesting them as needed but I’ve decided against this. I’m now planning on embedding the 3rd party API call in a cloud function and invoking that from my backend as I think I should avoid sensitive secrets being deployed in the native application.

Hi @ericmand!

I was looking into this yesterday a bit. I’m not super familiar with Flutter/Dart, but it seems like the only built-in way to inject environment variables at build time is via the --dart-define flag for Flutter or the --define flag with Dart. Some information I found said that you could pass multiple definitions to --dart-define like this: --dart-define=FOO=a,BAR=b,BAZ=c, but I wasn’t able to get that working. As such, it doesn’t appear as if there’s an easy way to simply pass environment variables in directly at command execution without a wrapper script.

That said, you can use a wrapper script like this to accomplish it:

#!/usr/bin/env bash

cmd="flutter run"

for secret in $(doppler secrets download --no-file --format env-no-quotes); do
  cmd="${cmd} --dart-define=${secret}"
done

eval $cmd

Once you’re passing in the variables, you can do something like this:

class EnvironmentConfig {
  static const DOPPLER_PROJECT = String.fromEnvironment('DOPPLER_PROJECT', defaultValue: 'unknown');
  static const FOO = String.fromEnvironment('FOO', defaultValue: 'unknown');
  static const BAR = String.fromEnvironment('BAR', defaultValue: 'unknown');
}

At that point, you can reference it using EnvironmentConfig.DOPPLER_PROJECT.

I’m certainly not an expert in this area, so it’s possible that there are better ways to do this (maybe @ryan-blunden has some ideas), but this does seem to work in the small amount of testing I was able to do.

For reference, here’s the articles I found that described this pattern:

It’s a bit dated, but has updates over time as new versions of Flutter came out. It may contain some other information that you find useful!

One other thing to keep in mind when designing your application is that Doppler does have an API rate limit described here. When the Doppler CLI fetches secrets as in the command above, that will count toward the API limit. If you were to use our API directly to fetch individual secrets on a per-request or per-client basis, then that will count toward the rate limit as well.

Let me know if the above proves useful for you!

Thanks @watsonian. This is very helpful. The only thing I don’t love about the wrapper is that I’m limited in how I can adjust the flutter build command (I think). Also, my CI system (codemagic) has a baked-in flutter build command that I can’t wrap- but does support executing scripts prior to build. Perhaps I can adjust this wrapper to assemble the dart-defines and secrets in advance and then pass them to a separately executed build command. I was imagining just exporting a bash variable with the full string of dart-defines. Not sure if that’ll work. Then for local, I’ll use a VSCode launch configuration to execute the pre-launch task to fetch the secrets and in CI I’ll execute that pre-build script option I mentioned. Does this make sense?

Yeah, I think that makes sense based on my limited knowledge around it. Regarding VS Code launch configs – I recommend checking out this thread as it contains some relevant info. I think there was/is a bug with flutter that you might hit. The user in that thread links to some GitHub issues they opened regarding them. Let me know how it goes! If a generally usable pattern can be found we’d love to get that in our documentation!