-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Working with multiple env files #16
Comments
You should be able to create 3 classes, e.g., |
@Isuru-Nanayakkara Did it work or have there been any problems? :) |
It technically works. However the problem is if I have 3 separate classes like that, wherever I have to access the env variables, I'll have to check which flavor I'm on at runtime and then call the relevant class. Which will result in a lot of switch case statements all over the codebase. Sooo not sure if that's the optimal way. I'm also thinking of a better way to handle this. |
@Isuru-Nanayakkara You were right. I also face the same situation. The better way is to use one entry to access the data. Maybe we can optimize the codegen. |
Would it be an idea to have the path to the env file in the builder config? Like buily.ci.yaml, build.test.yaml, build.yaml, build.dev.yaml The Build runner could potentially be called with
and inside the yaml we could have:
Think that would be a nice option. Just created this PR: Maybe if it is a good idea you can take it ^^ As example it would work like this:
|
@Isuru-Nanayakkara I similarly have this multi flavor setup. A solution my team and I came up with is to utilize some bash scripts to load my env from 1password which overwrites the If you are interested in this approach I can share my scripts with you here. |
@chillbrodev That's great! I already have my env files as base64 encoded strings in the CI/CD so that approach would be easy to implement. Please do share the script. Thank you. |
You would run this inside your flutter project. We have a scripts folder that we put a bunch of scripts in and check it in. Enjoy! Here is an example 1password secure note:
Here is the 1password script (Replace the values with your values): # log in to 1Password
eval $(op signin --account <1passwordAccount>)
# Get exit code from `op whoami` since eval always returns 0
op whoami > /dev/null
if [ $? -ne 0 ]; then
echo "Error: 1Password login failed"
exit 1
fi
echo "Getting flutter dev env vars from 1Password..."
# get pem from 1Password
DEV_ENVS=$(op item get "<Secured Note>" --vault <1password Vault> --format json | jq '.fields[0].value' | sed "s/\"\(.*\)\"/\1/" | sed 's/\\"/"/g')
ENV=".env"
echo $DEV_ENVS > $ENV |
Thanks so much @chillbrodev 🙂 Appreciate it! I'll give it a try. |
Sounds great, lemme know if you run into any issues or need further help. |
Coming from JS and Ruby I'm used to the pattern that there's a base Here's a nice inheritance breakdown from the classic ruby dotenv: |
@ctsstc I would think that this can already be done using That is also the reason why I think that #20 won't change too much about the issue at hand: You still need to change the |
Maybe can use someking like FirebaseOptions generation, use a superclass on a bootstrap param. |
I simply hope to stop using "static" values. Like this
Then, We can switch like this
|
Why do you need to use a whole separate instance of Envied? Assuming your keys are the same across Dev/Production, you could change out the .env file before you deploy to production. |
The design I described above is incorrect. I was thinking about an app that includes a developer mode, so initially, I wanted to deploy it with multiple environment configurations. |
Hello All, I am Pretty new to Flutter. just want to understand how will i run production enviornment using flutter run ? I want to run my application in production mode, using flutter run. i tried few things but it didnt work |
I had the same problem but was able to create a temporary solution using a singleton class and package_info_plus package. Since using 3 different classes made things really hard, I had to reduce the stress and decided to add the variables(both dev and prod) to just one .env file. Just append "dev" or "prod" to the key names. E.g
Then do the following: Step 1:
Step 2:
After generating your env classes,
This is our temporary solution but I hope it helps! |
@skibble-app Why not just use |
@ThexXTURBOXx Yes, I tried that but there is a problem. You can have a dev, stg and prod flavors and they each would come in 3 variants (debug, profile & release). So if you ran the prod or stg flavor in debug mode, kDebugMode will always return true. The distinct feature in all the flavors is the bundle id. |
@petercinibulk If we could have a CLI for envied this will be very generic and we would be able to use in any situations. Use case #1 - Development mode (local machine)you can use the usual suspect : Use case #2 - Build with CI/CD pipelineI think this will work whatever you are using flavors or not. Can can have a task before calling the flutter build:
|
This is covered in an example. Duplicate of #44 |
@techouse I'm not sure using Also there can be more than 2 environments than dev and prod. The |
@Isuru-Nanayakkara depends on your situation. I just gave an example of using an out-of-the-box deterministic way of differentiating configs. The example should NOT be verbatim copied into your app. It's up to the developer to find the best way of determining which config to load. I even pointed that out on line 6. I suggest you use Flutter flavors to solve this. Using flavors you can pass the corresponding flavor to the flutter build command using the flutter build ipa --release --flavor staging and then parse that in your app into an |
Yes, I'm already using flavors/schemes for environments. The problem I was facing was, as per the package's design, I'd have to generate multiple envied files. I was wondering if there was a way to extend the package to avoid that. |
Isn't separation of different env variables into multiple env files a good thing? I'm quite opposed to the idea of having a huge switch statement in a single file. |
Totally agreed on both counts. My intention is to avoid switch statements too. Please see my current way of handling environment values in this repo.
flavorDimensions "flavors"
productFlavors {
dev {
dimension "flavors"
resValue "string", "app_name", "(Dev) SuperCoolApp"
applicationIdSuffix ".dev"
}
qa {
dimension "flavors"
resValue "string", "app_name", "(QA) SuperCoolApp"
applicationIdSuffix ".qa"
}
prod {
dimension "flavors"
resValue "string", "app_name", "SuperCoolApp"
}
}
dev.env
import 'package:flutter_dotenv/flutter_dotenv.dart';
enum Environment {
dev,
qa,
prod,
}
class EnvironmentValues {
static final EnvironmentValues _instance = EnvironmentValues._();
static Environment? _environment;
EnvironmentValues._();
static EnvironmentValues get instance => _instance;
static Future load({required env, required String fileName}) async {
_environment = env;
await dotenv.load(fileName: fileName);
}
static Environment get environment {
return _environment!;
}
static String get apiBaseURL {
return dotenv.get('API_URL');
}
}
void main() async {
await EnvironmentValues.load(
env: Environment.dev,
fileName: 'env/dev.env',
);
runApp(const App());
} This works great. I can switch between flavors and everything would just work. No need for conditional statements anywhere in the code to check for the current environment since it's handled at launch at the main entry point. @override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text(EnvironmentValues.apiBaseURL),
),
);
} The only downside is the security aspect. Hence I looked to use envied. Essentially I was trying to replace my |
You mean as in committing the env vars to Github?
I use multiple files personally. I generate them all at once and based on the run/compilation I need I load them at compile time. I do not track them in git. |
No no, I mean obfuscating the values. I have read somewhere that since env files need to be added as assets in the Flutter bundle, they can be extracted. I wanted to try envied since it supports obfuscation.
How do you use it in your code? Since you're creating multiple files, I'm assuming you'll have separate files like EnvDev, EnvProd etc? So when you need to access a value like so Env.key1, won't you need to use conditional statements in that case? |
Yeah, even though that's nice it can still be decrypted / deobfuscated. Treat any value you put into a client app as public, just as you would with JavaScript. It's public and should NOT be of a sensitive nature.
Pretty much the same way as I've done it in the example abstract interface class AppEnv {
factory AppEnv() => _instance;
static final AppEnv _instance = kDebugMode
? DebugEnv()
: kProfileMode
? ProfileEnv()
: kBuildFlavor == Flavor.qa
? QaEnv()
: ReleaseEnv();
} |
The solution for flavors is described here |
That is a solution but I would not say it is THE solution. Ideally the app should use 1 .env file and it is up to the developer to properly update the .env file with the correct values for each flavor. I describe usage above #16 (comment) |
Hi,
I usually have 3 flavors in my projects - dev, QA and prod. And I create env files for each flavor.
But using envied, I have to point it to a single env file.
Now if I want to switch between running different flavor, I have to manually edit the env path and run code generation every time.
Is there a better way to do this using envied?
The text was updated successfully, but these errors were encountered: