شارك المقالة

flutter_dotenv في Flutter من أفضل الطرق لإدارة الإعدادات القابلة للتغيير داخل تطبيقك، مثل روابط الخوادم، مفاتيح الخدمات، إعدادات التتبع، أو أي قيم لا تريد كتابتها مباشرة داخل الكود.

إذا كنت تطوّر تطبيق Flutter وتريد فصل الإعدادات عن الشيفرة المصدرية، فمكتبة flutter_dotenv تمنحك طريقة بسيطة ومرنة للتعامل مع ملفات .env داخل المشروع.

في هذا المقال سنتعلم شرح flutter_dotenv في Flutter خطوة بخطوة، بداية من التثبيت، ثم إنشاء ملف .env، وتحميله داخل التطبيق، واستخدام القيم داخل Dart، بالإضافة إلى التعامل مع Android و iOS وأفضل الممارسات المهمة.

ما هي مكتبة flutter_dotenv؟

مكتبة flutter_dotenv هي مكتبة تساعدك على قراءة المتغيرات الموجودة داخل ملف .env داخل تطبيق Flutter.

بدل ما تكتب القيم الثابتة داخل الكود مباشرة مثل:

const baseUrl = "https://www.google.com";

تقدر تضعها داخل ملف .env بالشكل التالي:

BASE_URL=https://www.google.com

وبعدها تقرأها داخل التطبيق باستخدام:

dotenv.env['BASE_URL']

لماذا نستخدم .env في Flutter؟

استخدام ملفات .env داخل Flutter له فوائد كثيرة، خصوصًا في المشاريع المتوسطة والكبيرة.

  • فصل الإعدادات عن الكود الأساسي
  • سهولة تغيير رابط السيرفر بدون تعديل الشيفرة
  • دعم أكثر من بيئة مثل development و staging و production
  • تنظيم مفاتيح الخدمات الخارجية
  • تقليل تكرار القيم داخل ملفات المشروع
  • تسهيل عملية البناء والنشر

تنبيه مهم قبل استخدام flutter_dotenv

لازم تعرف نقطة مهمة جدًا:

في تطبيقات Flutter، أي ملف .env تضيفه داخل assets سيكون موجودًا داخل حزمة التطبيق، وبالتالي يمكن الوصول إليه عند تحليل التطبيق.

لذلك لا تضع أسرار حساسة جدًا داخل ملف .env مثل:

  • Private API Keys
  • Database Passwords
  • Secret Tokens
  • Payment Secret Keys

ملف .env مناسب أكثر للقيم القابلة للتغيير، وليس للأسرار التي يجب أن تبقى مخفية تمامًا.

تثبيت flutter_dotenv في Flutter

أول خطوة هي إضافة المكتبة داخل ملف pubspec.yaml.

dependencies:
  flutter:
    sdk: flutter

  flutter_dotenv: ^6.0.0

بعد إضافة المكتبة، شغل الأمر التالي لتحميل الحزمة:

flutter pub get

إنشاء ملف .env داخل مشروع Flutter

داخل جذر المشروع، أنشئ ملف جديد باسم:

.env

ثم أضف القيم التي تريد استخدامها داخل التطبيق.

BASE_URL=https://www.google.com
API_KEY=abc12345
APP_ENV=development

في المثال السابق عندنا:

  • BASE_URL: رابط السيرفر أو API
  • API_KEY: مفتاح خدمة خارجي
  • APP_ENV: اسم البيئة الحالية

تعريف ملف .env داخل pubspec.yaml

حتى يستطيع Flutter قراءة ملف .env، لازم تضيفه داخل قسم assets في ملف pubspec.yaml.

flutter:
  assets:
    - .env

انتبه جيدًا للمسافات داخل ملف pubspec.yaml لأن أي خطأ في الـ indentation ممكن يسبب مشكلة أثناء تشغيل التطبيق.

تحميل ملف .env قبل تشغيل التطبيق

لازم يتم تحميل ملف .env قبل تشغيل التطبيق باستخدام runApp.

افتح ملف main.dart واكتب الكود التالي:

import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await dotenv.load(fileName: ".env");

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    final baseUrl = dotenv.env['BASE_URL'];

    return MaterialApp(
      title: 'Env Demo',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('flutter_dotenv مثال'),
        ),
        body: Center(
          child: Text('BASE_URL: $baseUrl'),
        ),
      ),
    );
  }
}

شرح الكود السابق

في البداية قمنا باستدعاء مكتبة flutter_dotenv:

import 'package:flutter_dotenv/flutter_dotenv.dart';

بعد ذلك استخدمنا:

WidgetsFlutterBinding.ensureInitialized();

هذه الخطوة مهمة لأننا نحتاج إلى تحميل ملف .env قبل تشغيل التطبيق.

ثم قمنا بتحميل الملف:

await dotenv.load(fileName: ".env");

وبعدها قرأنا قيمة BASE_URL:

final baseUrl = dotenv.env['BASE_URL'];

قراءة قيمة من ملف .env

لقراءة أي قيمة من ملف .env، استخدم الشكل التالي:

final baseUrl = dotenv.env['BASE_URL'];

ولو عايز تضيف قيمة افتراضية في حالة أن المتغير غير موجود، يمكنك استخدام:

final baseUrl = dotenv.env['BASE_URL'] ?? 'https://default-url.com';

وهذا مفيد جدًا لتجنب ظهور قيمة null داخل التطبيق.

مثال عملي لاستخدام BASE_URL مع API

بدل ما تكتب رابط API مباشرة داخل الكود، يمكنك قراءته من ملف .env.

class ApiConfig {
  static String baseUrl = dotenv.env['BASE_URL'] ?? '';
}

ثم تستخدمه في أي مكان داخل التطبيق:

final url = '${ApiConfig.baseUrl}/users';

بهذا الشكل لو تغير رابط السيرفر، كل ما عليك هو تعديل ملف .env فقط.

استخدام أكثر من ملف env في Flutter

في المشاريع الحقيقية غالبًا تحتاج أكثر من بيئة، مثل:

  • بيئة التطوير Development
  • بيئة الاختبار Staging
  • بيئة الإنتاج Production

يمكنك إنشاء أكثر من ملف:

.env.development
.env.staging
.env.production

مثال على ملف .env.development:

BASE_URL=https://dev.example.com
APP_ENV=development

مثال على ملف .env.production:

BASE_URL=https://api.example.com
APP_ENV=production

ثم تختار الملف المناسب أثناء التحميل:

await dotenv.load(fileName: ".env.development");

استخدام flutter_dotenv مع AndroidManifest.xml

في بعض الحالات قد تحتاج إلى استخدام قيمة من .env داخل ملف AndroidManifest.xml، مثل مفاتيح Google Maps أو Firebase أو أي خدمة تحتاج meta-data.

مثال داخل ملف .env:

API_KEY=abc12345

داخل ملف android/app/build.gradle يمكنك تعريف القيمة واستخدامها كـ placeholder.

def apiKey = project.hasProperty("API_KEY") ? project.property("API_KEY") : ""

android {
    defaultConfig {
        manifestPlaceholders = [
            API_KEY: apiKey
        ]
    }
}

ثم داخل ملف AndroidManifest.xml:

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="${API_KEY}" />

طريقة بديلة لاستخدام key.properties في Android

ممكن تستخدم ملف key.properties داخل Android لقراءة القيم المطلوبة.

أنشئ ملف:

android/key.properties

ثم أضف داخله:

API_KEY=abc12345

بعد ذلك اقرأ الملف داخل android/app/build.gradle:

def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')

if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

def apiKey = keystoreProperties['API_KEY'] ?: ""

android {
    defaultConfig {
        manifestPlaceholders = [
            API_KEY: apiKey
        ]
    }
}

ثم استخدم القيمة داخل AndroidManifest.xml بنفس الطريقة:

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="${API_KEY}" />

استخدام API_KEY داخل iOS

لو شغال على iOS وتحتاج تمرير قيمة إلى ملف Info.plist، يمكنك إضافة المفتاح بالشكل التالي:

<key>API_KEY</key>
<string>$(API_KEY)</string>

بعد ذلك افتح Xcode واتبع الخطوات التالية:

  • افتح مشروع iOS من داخل Xcode
  • اذهب إلى Runner
  • افتح Build Settings
  • أضف متغير باسم API_KEY
  • ضع القيمة المناسبة للمتغير

ويمكنك قراءة القيمة داخل AppDelegate.swift بهذا الشكل:

if let apiKey = Bundle.main.object(forInfoDictionaryKey: "API_KEY") as? String {
    print("iOS API Key: \(apiKey)")
}

هل flutter_dotenv آمن لتخزين الأسرار؟

الإجابة المختصرة: لا تعتمد عليه لتخزين أسرار حساسة جدًا داخل تطبيق العميل.

لأن تطبيق Flutter يتم تثبيته على جهاز المستخدم، وأي ملف موجود داخل التطبيق يمكن الوصول إليه بطرق مختلفة.

استخدم flutter_dotenv في Flutter لتخزين إعدادات مثل:

  • روابط API العامة
  • اسم البيئة الحالية
  • مفاتيح Public API
  • إعدادات التتبع غير الحساسة

ولا تستخدمه لتخزين:

  • Secret Token
  • Database Password
  • Private Key
  • Payment Secret Key

بدائل أكثر أمانًا للأسرار الحساسة

لو عندك مفاتيح حساسة جدًا، الأفضل عدم وضعها داخل تطبيق Flutter مباشرة.

بدلًا من ذلك، استخدم واحدًا من الحلول التالية:

  • Backend Server لإخفاء المفاتيح الحساسة
  • Remote Config مثل Firebase Remote Config
  • CI/CD Secrets وقت البناء
  • Native Secure Storage لبعض الحالات الخاصة

مشاكل شائعة عند استخدام flutter_dotenv

مشكلة Unable to load asset .env

لو ظهر لك هذا الخطأ، غالبًا السبب أن ملف .env غير مضاف داخل pubspec.yaml.

تأكد من إضافة الملف:

flutter:
  assets:
    - .env

القيمة ترجع null

لو كانت القيمة ترجع null، تأكد من النقاط التالية:

  • اسم المتغير مكتوب بشكل صحيح
  • ملف .env تم تحميله قبل runApp
  • لا توجد مسافات غير صحيحة حول علامة =

التطبيق لا يقرأ التعديلات الجديدة

بعد تعديل ملف .env، أوقف التطبيق وشغله مرة أخرى.

وفي بعض الحالات يمكنك تشغيل:

flutter clean
flutter pub get
flutter run

أفضل الممارسات عند استخدام flutter_dotenv

  • لا تضع أسرار حساسة داخل ملف .env في تطبيق العميل
  • أضف ملفات البيئة غير العامة إلى .gitignore
  • استخدم ملف .env.example لتوضيح المتغيرات المطلوبة للفريق
  • حمّل ملف .env قبل تشغيل التطبيق
  • استخدم قيم افتراضية عند قراءة المتغيرات
  • قسّم ملفات البيئة حسب نوع البيئة مثل development و production

مثال على ملف .gitignore

يفضل ألا ترفع ملفات البيئة الحقيقية إلى GitHub إذا كانت تحتوي على إعدادات خاصة.

.env
.env.development
.env.staging
.env.production

وبدلًا من ذلك، أضف ملفًا توضيحيًا باسم:

.env.example

مثال على محتوى الملف:

BASE_URL=
API_KEY=
APP_ENV=

الخلاصة

تعتبر مكتبة flutter_dotenv في Flutter حلًا بسيطًا وعمليًا لإدارة ملفات .env وفصل الإعدادات عن الكود الأساسي.

من خلالها يمكنك تخزين روابط الخوادم، أسماء البيئات، وبعض مفاتيح الخدمات العامة، ثم قراءتها بسهولة داخل تطبيق Flutter.

لكن يجب الانتباه إلى أن ملفات .env داخل تطبيقات العميل ليست مكانًا آمنًا للأسرار الحساسة جدًا، لذلك استخدمها فقط للإعدادات القابلة للتغيير، واعتمد على Backend أو CI/CD Secrets لحماية المفاتيح المهمة.

في النهاية، إذا كنت تريد تنظيم إعدادات مشروعك وتقليل التعديلات المباشرة داخل الكود، فإن استخدام flutter_dotenv في Flutter يعتبر اختيارًا ممتازًا وسهل التطبيق.



لمزيد من المقالات : تحويل Array of object الى ملف pdf باستخدام kotlin
شاهد أيضًا
مقالات ذات صلة

🚫 مانع الإعلانات مفعل

يجب إيقاف مانع الإعلانات لاستكمال تصفح الموقع