كيفية نشر تطبيق Flutter على Google Play
نشر تطبيق Flutter على Google Play ليس مجرد ضغط زر أخير ثم انتظار السحر. هو في الحقيقة المرحلة التي يتحول فيها التطبيق من مشروع محلي على جهازك إلى منتج حقيقي يراه المستخدمون، ويجربونه، ويحكمون عليه من أول دقيقة. ولهذا السبب، من الأفضل أن تتعامل مع عملية النشر كأنها جزء من تطوير التطبيق نفسه، لا كخطوة جانبية في آخر الطريق. التوثيق الرسمي لـ Flutter يضع النشر ضمن سلسلة واضحة تبدأ من التحضير، ثم التوقيع، ثم بناء نسخة إصدار، ثم الرفع إلى Google Play، بينما توثيق Google Play وAndroid يوضحان أن الصيغة المفضلة للنشر هي Android App Bundle، وأن Play App Signing هو الأسلوب المعتمد لنشر التطبيقات الجديدة عبر المتجر.
إذا كنت تنشر تطبيقك لأول مرة، فغالبًا ستشعر بشيء من التوتر: هل التوقيع صحيح؟ هل رقم الإصدار مضبوط؟ هل المتجر سيقبل النسخة؟ هل هناك خطوة نسيتها؟ هذا طبيعي جدًا، ولذلك سأمشي معك هنا من البداية حتى لحظة الرفع، وكأننا نراجع التطبيق قبل تسليمه فعليًا إلى الناس. الجميل في Flutter أنه يختصر عليك الكثير من التعقيد، لكن النشر على Google Play ما زال يحتاج إلى انضباط في التهيئة، لأن أي خطأ صغير في التوقيع أو رقم النسخة أو إعدادات Play Console يمكن أن يوقفك عند آخر خطوة.
قبل أن تبدأ: ما الذي يجب أن يكون جاهزًا؟
قبل التفكير في أمر النشر نفسه، تأكد أن التطبيق يعمل بشكل مستقر في وضع التطوير وأنك اختبرته على جهاز حقيقي أو على محاكي مناسب. صفحة Flutter الخاصة ببناء ونشر تطبيق Android تذكر بوضوح أن الاختبار يمكن أن يتم عبر flutter run أو من داخل بيئة التطوير، ثم بعدها تبدأ مرحلة إصدار النسخة النهائية. هذه النقطة مهمة لأن كثيرًا من المشكلات التي تظهر عند النشر لا تكون في النشر نفسه، بل في أشياء تم تجاهلها في وقت سابق: أيقونة التطبيق، إعدادات الـ manifest، توافق الإصدارات، أو حتى اسم الحزمة.
أول شيء أنصح به دائمًا هو أن ترتب مشروعك قبل أي عملية build نهائية. راجع اسم الحزمة applicationId، وراجع صورة الأيقونة، وتأكد أن كل شاشة تفتح وتغلق بشكل طبيعي، وأن التسجيل والدخول والشراء والإشعارات وأي تكامل مع خدمة خارجية يعمل كما يجب. توثيق Flutter يلفت الانتباه إلى أشياء عملية جدًا قبل النشر مثل إضافة launcher icon، مراجعة manifest، مراجعة إعدادات البناء، وتقليل الحجم عبر R8، وكلها نقاط تصنع فرقًا واضحًا عند الانتقال إلى Play Store.
فهم الفكرة الأساسية: لماذا نستخدم AAB بدل APK؟
الخطأ الشائع عند كثير من المطورين الجدد هو أنهم يظنون أن ملف APK هو الصيغة النهائية الوحيدة للنشر. هذا لم يعد الخيار الأفضل على Google Play، لأن Google تفضّل Android App Bundle، وهو تنسيق نشر يحتوي على الكود والموارد المترجمة للتطبيق، ثم تتولى Google Play توليد APKs المناسبة لكل جهاز تلقائيًا. هذا الأسلوب يقلل حجم التنزيل، ويجعل التوزيع أكثر كفاءة، ويخفف عنك عبء بناء عدة ملفات APK لكل معمارية.
Flutter ينسجم مع هذا النهج بشكل ممتاز. التوثيق الرسمي يذكر أن أوامر الإصدار في Android تنتج ملف AAB في المسار build/app/outputs/bundle/release/app.aab عند استخدام flutter build appbundle، كما يوضح أن الحزمة النهائية تتضمن Dart runtime والتطبيق مترجمًا لعدة معماريات مدعومة. هذا يعني أنك في أغلب الحالات لن تحتاج إلى إنتاج APK للنشر على المتجر نفسه، إلا في حالات اختبار أو توزيع خارجي أو لظروف محددة جدًا.
إعداد رقم الإصدار بطريقة صحيحة
رقم الإصدار من أكثر التفاصيل التي يستهين بها البعض ثم يكتشفون لاحقًا أنه سبب الرفض. Flutter يقرأ versionName وversionCode من ملف pubspec.yaml بصيغة مثل 1.0.0+1، وعند البناء على Android يتم استخدام build-name كـ versionName وbuild-number كـ versionCode. عند إعادة البناء، يتم تحديث هذه القيم داخل إعدادات المشروع، ولذلك يجب أن تكون حريصًا على زيادة رقم البناء كلما أصدرت نسخة جديدة.
الطريقة العملية تكون كالتالي: عندما تطلق النسخة الأولى، يمكنك وضع رقم مثل 1.0.0+1. في النسخة الثانية، ارفع البناء إلى 1.0.0+2 أو غيّر الاسم أيضًا إلى 1.1.0+2 إذا كانت هناك تحسينات حقيقية للمستخدم. Google Play يحتاج إلى versionCode أعلى في كل تحديث جديد، وإلا فلن يعتبر الملف الجديد تحديثًا صالحًا. التوثيق الخاص برفع الحزم إلى Play Console يذكر صراحةً أن التحديث يتطلب زيادة version code داخل base module ثم بناء ورفع bundle جديد.
مثال بسيط في pubspec.yaml:
version: 1.0.0+1
وعند التحديث قد يصبح:
version: 1.0.1+2
هذه ليست مجرد أرقام شكلية. هي إشارة للمتجر وللنظام بأن هذا الملف أحدث من السابق، وأنه يستحق أن يحل محل النسخة القديمة.
إنشاء keystore للتوقيع
واحدة من أهم الخطوات، وربما أكثرها حساسية، هي التوقيع. Android يشترط توقيع كل APK أو App Bundle بشهادة رقمية قبل التثبيت أو التحديث، وعند النشر عبر App Bundle تحتاج إلى توقيع الحزمة بمفتاح رفع upload key، بينما يتولى Play App Signing بقية العملية. Flutter يوجّهك إلى إنشاء upload keystore أولًا، ثم ربطه بالمشروع، ثم إعداد Gradle لاستخدامه في وضع release.
يمكنك إنشاء keystore عبر Android Studio، أو عبر سطر الأوامر. المثال الرسمي في توثيق Flutter يوضح أوامر keytool التالية، وهي من الطرق الشائعة والعملية:
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA \
-storetype JKS -keysize 2048 -validity 10000 -alias upload
وعلى Windows:
keytool -genkey -v -keystore $env:USERPROFILE\upload-keystore.jks `
-storetype JKS -keyalg RSA -keysize 2048 -validity 10000 `
-alias upload
المهم هنا ليس حفظ الأمر فقط، بل فهم الفكرة: هذا الملف هو هويتك في عملية التوقيع، ولذلك يجب أن يبقى سريًا ولا يوضع في مستودع عام. التوثيق الرسمي يحذر بوضوح من مشاركة ملف keystore أو رفعه إلى source control العام.
ربط keystore بالمشروع
بعد إنشاء keystore، ستحتاج إلى تعريفه داخل المشروع. Flutter يقترح إنشاء ملف android/key.properties يحتوي على بيانات التوقيع، مثل كلمة المرور واسم الـ alias وموقع الملف. الشكل الأساسي يكون قريبًا من هذا:
storePassword=your_store_password
keyPassword=your_key_password
keyAlias=upload
storeFile=/Users/yourname/upload-keystore.jks
إذا كنت على Windows، فغالبًا ستحتاج إلى مسار بصيغة تتضمن backslashes مزدوجة. مرة أخرى، النقطة الأهم هنا ليست شكل الملف فقط، بل عدم كشفه في أي مستودع عام أو مشاركته ضمن الفريق إلا بالقدر الضروري وبطريقة آمنة. Flutter يصرّح بأن ملف key.properties يجب أن يبقى خاصًا أيضًا.
إعداد Gradle للتوقيع
الخطوة التالية هي إخبار Gradle بمفتاح التوقيع. التوثيق الرسمي لـ Flutter يذكر أن التعديل يتم داخل android/app/build.gradle.kts أو النسخة Groovy حسب المشروع، ثم يتم تحميل key.properties قبل بلوك android. بعدها تصبح نسخة الإصدار موقعة بالمفتاح الصحيح عند البناء. هذا الجزء حاسم جدًا لأن أي خطأ فيه سيؤدي غالبًا إلى ملف غير صالح للرفع أو إلى توقيع خاطئ يرفضه Play Console.
مثال توضيحي مبسط لـ Kotlin DSL:
import java.util.Properties
import java.io.FileInputStream
val keystorePropertiesFile = rootProject.file("android/key.properties")
val keystoreProperties = Properties()
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
android {
signingConfigs {
create("release") {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["storePassword"] as String
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
}
}
}
هذا المثال للتوضيح فقط، لكن الفكرة الأساسية هي نفسها: ربط build type الخاص بالإصدار بمعلومات التوقيع الموجودة في الملف السري، حتى تستطيع إنشاء نسخة release سليمة وجاهزة للرفع. التوثيق الرسمي يشرح نفس المسار على نحو مشابه ويقسمه إلى إنشاء keystore، ثم الإشارة إليه من داخل التطبيق، ثم إعداد التوقيع في Gradle.
تفعيل Play App Signing
اليوم، نشر تطبيقات Android الجديدة على Google Play يعتمد على Play App Signing، والوثائق الرسمية تشير إلى أنه الطريقة الموصى بها، بل وتذكر أن الانضمام إليه أصبح إلزاميًا لرفع وتوقيع التطبيقات الجديدة منذ أغسطس 2021. الفكرة هنا أن Google تحتفظ بمفتاح التوقيع النهائي وتحميه عبر البنية الآمنة الخاصة بها، بينما تحتفظ أنت بمفتاح الرفع upload key لتوقيع الحزمة التي سترفعها. هذا يخفف عنك مسؤولية إدارة المفتاح النهائي ويزيد مستوى الأمان.
عمليًا، عند إنشاء الإصدار الجديد في Play Console، يتم تفعيل Play App Signing تلقائيًا في كثير من الحالات عند رفع AAB، وقد يختار Play Console إنشاء مفتاح RSA 4096-bit وإدارته نيابةً عنك. التوثيق الرسمي يذكر أن أكثر من 90% من التطبيقات الجديدة تستخدم هذا المسار الافتراضي الموصى به، وأنه لا يتطلب عادةً أي إجراء إضافي بعد رفع الحزمة. كما يوضح أن المفاتيح المستخدمة في Play App Signing تتم حمايتها عبر Google’s Key Management Service.
هذا لا يعني أنك تتخلى عن السيطرة، بل يعني أن النظام أصبح أكثر أمانًا ومرونة. إذا كنت تحتاج إلى إدارة key خاص بك أو نقل مفتاح موجود أو استخدام مفتاح توقيع مخصص، فهناك إجراءات رسمية لذلك داخل Play Console، بما في ذلك نقل نسخة من مفتاحك الأصلي أو اختيار مفتاح آخر، لكن أغلب التطبيقات الجديدة لن تحتاج إلى تعقيد إضافي.
بناء ملف الإطلاق AAB
بعد أن أصبح التوقيع جاهزًا، يأتي وقت البناء. في Flutter، الأمر الأهم هو:
flutter build appbundle
التوثيق الرسمي يذكر أن هذا الأمر ينشئ ملف الإصدار في المسار:
build/app/outputs/bundle/release/app.aab
كما يذكر أيضًا أن تنفيذ flutter build وحده ينتج build release افتراضيًا. لذلك، إن كنت تريد نسخة مخصصة للنشر على Google Play، فـ AAB هو الخيار الطبيعي والأفضل.
وهنا نقطة لطيفة لكنها مهمة: لا تنتظر حتى آخر لحظة لتجربة أمر البناء. جرّب بناء release مبكرًا خلال التطوير، لأنك قد تكتشف مشاكل في التوقيع أو الموارد أو الـ manifest أو توافق SDK قبل أن تصل إلى يوم النشر الفعلي. التوثيق الرسمي لـ Flutter يضع اختبار bundle ضمن الخطوات نفسها، وهذا ليس عبثًا؛ إنه جزء من تقليل المفاجآت.
اختبار bundle قبل الرفع
النسخة التي تعمل على جهازك أثناء التطوير ليست ضمانًا أن نسخة الإصدار النهائية ستمر بلا مشاكل. Flutter يشير إلى أكثر من طريقة لاختبار الحزمة، منها الاختبار عبر bundletool أو عبر Play Console نفسها. كما يذكر Android Studio أن Play Console يولد split APKs وmulti-APKs تلقائيًا من App Bundle، ويمكنك فحصها من قسم Latest bundles أو تنزيلها لاختبارها محليًا.
إذا أردت اختبارًا أكثر واقعية، فابدأ بإنشاء نسخة release فعلية ثم ثبتها على جهازك أو وزعها داخليًا. Google Play يوفر آليات توزيع داخلي مثل internal app sharing، وكذلك توجد أدوات مثل Firebase App Distribution للتوزيع الداخلي. هذا مفيد جدًا عندما يكون لديك فريق أو مختبرون تريد أن تجرب معهم قبل الخروج إلى الإنتاج.
في كثير من الحالات، أفضل طريقة هي أن تختبر كالتالي: تبني AAB، تتأكد أنه تم إنشاؤه في مكانه الصحيح، ثم ترفع نسخة داخلية أو closed testing، وتفتح التطبيق على عدة أجهزة، وتختبر تسجيل الدخول والتنقل والاتصال بالشبكة والإشعارات وعمليات الشراء داخل التطبيق إن وُجدت. هذه الخطوات قد تبدو طويلة، لكنها تختصر عليك مراجعات وأخطاء نشر مؤلمة لاحقًا.
إنشاء التطبيق في Play Console
بعد تجهيز الحزمة، تحتاج إلى Play Console. توثيق Google Play يوضح أن عليك أولًا إنشاء حساب Google Play Developer، ثم يمكنك إنشاء التطبيق من داخل Play Console عبر Home > Create app، ثم اختيار اللغة الافتراضية واسم التطبيق ونوعه. بعد ذلك يبدأ إعداد بيانات المتجر، ومعلومات المحتوى، وخطة الإصدار.
الخطوة هنا ليست تقنية فقط، بل تنظيمية أيضًا. عندما تنشئ التطبيق، أنت تدخل مرحلة جديدة: مرحلة بيانات المتجر، وصف التطبيق، الأيقونة، لقطات الشاشة، سياسة الخصوصية، التصنيف العمري، والجمهور المستهدف. Google Play Console يوجهك عبر هذه المراحل على لوحة التطبيق نفسها، ويذكر أن الخطوة النهائية هي إطلاق التطبيق ليصبح متاحًا للمستخدمين.
إعداد صفحة المتجر Store Listing
لا تستخف بصفحة المتجر، فهي في كثير من الأحيان أول انطباع عن تطبيقك. Google Play يركز على جودة وصف التطبيق وعناصر الصفحة لأنهما يؤثران على الثقة والقبول. التوجيهات الرسمية تذكر أيضًا أن الأصول الترويجية مثل الصور والفيديوهات يمكن إدارتها من قسم Main store listing ضمن Store presence، وأن جودة صفحة المتجر يجب أن تكون متوافقة مع سياسات Google Play.
اجعل الوصف واضحًا، بسيطًا، وصادقًا. لا تبالغ في الوعود، ولا تكتب كلمات دعائية مبالغًا فيها على حساب الفائدة الحقيقية. المستخدم لا يريد فقرة تسويقية طويلة بقدر ما يريد أن يفهم سريعًا: ماذا يفعل التطبيق؟ لمن هو؟ ولماذا يستحق التجربة؟ هذه ليست مجرد نصيحة ذوقية، بل جزء من تحسين صفحة المتجر بما يتوافق مع أفضل الممارسات التي تشير إليها Google Play.
التصنيف العمري والجمهور المستهدف
قبل النشر، ستحتاج إلى إكمال استبيان التصنيف العمري في Play Console. توثيق Google يوضح أن التصنيف يعتمد على إجاباتك عن طبيعة محتوى التطبيق، وأن إعطاء معلومات غير دقيقة قد يؤدي إلى مشاكل مثل الحذف أو التعليق أو الرفض. كما يطلب منك Google Play تحديد الجمهور المستهدف ومراعاة سياسات التوافق، خصوصًا إذا كان التطبيق موجهًا للأطفال أو لفئة عمرية خاصة.
هذا الجزء قد يبدو إداريًا، لكنه مهم جدًا. إذا كان تطبيقك يتضمن مشاركة محتوى، دردشة، إعلانات، أو جمع بيانات، فراجع الإجابات بعناية وكن دقيقًا. Google يراجع هذه المعلومات، وبعض الحسابات أو الفئات قد تخضع لمراجعة أطول من المعتاد. لذلك من الحكمة أن تتعامل مع هذا القسم بصدق كامل، لا على طريقة “دعنا نمر الآن ونصحح لاحقًا”.
إعداد سياسة الخصوصية والأذونات
إذا كان تطبيقك يجمع بيانات أو يستخدم أذونات حساسة أو يعتمد على تسجيل الدخول أو التحليلات أو الخرائط أو الكاميرا أو الموقع، فغالبًا ستحتاج إلى سياسة خصوصية واضحة. هذا ليس مجرد إجراء شكلي، بل جزء من التوافق مع متطلبات المتجر وثقة المستخدم. Play Console يوجهك داخل صفحة App content ومناطق إعداد المحتوى والجمهور المستهدف، ويطلب إكمال الإفصاحات المرتبطة بالتطبيق قبل الإطلاق.
من الأفضل أن تكتب سياسة خصوصية مباشرة وصريحة تتحدث عن البيانات التي يجمعها التطبيق، سبب جمعها، مدة الاحتفاظ بها، وكيفية حذفها أو طلب حذفها. لو كان تطبيقك بسيطًا جدًا ولا يجمع بيانات، فراجع المتطلبات بعناية أيضًا، لأن مجرد وجود SDKs خارجية أو تحليلات قد يغير الموقف. وفي كل الأحوال، تأكد أن صفحة المتجر وما يظهر داخل التطبيق ينسجان معًا قصة واحدة واضحة.
رفع ملف AAB إلى Play Console
بعد تجهيز كل شيء، اذهب إلى الإصدار المناسب داخل Play Console وارفع ملف app.aab. توثيق Android Studio يوضح أنك بعد توقيع نسخة الإصدار، ترفعها إلى Google Play لتفقدها واختبارها ونشرها. كما يذكر أن Play Console يولد تلقائيًا نسخ APK المناسبة للأجهزة المختلفة بعد رفع App Bundle.
عند الرفع، تحقق من التحذيرات التي تظهر لك. قد يخبرك النظام بوجود مشكلة في التوقيع، أو بضرورة إكمال إعدادات المتجر، أو بوجود نقص في قسم App content، أو باختلاف في رقم الإصدار. لا تتجاهل هذه الرسائل؛ فغالبًا هي الاختصار الذي ينقذك من الرفض لاحقًا. التوثيق الرسمي يبين أن الإكمال يتضمن أيضًا مراجعة إعدادات التسعير، وبيانات المتجر، وإجراءات ما قبل الإطلاق قبل أن تتمكن من نشر النسخة للعامة.
الفرق بين internal testing وclosed testing وproduction
من أفضل الممارسات ألا تقفز مباشرة إلى الإنتاج. Google Play Console يوفر مراحل اختبار متعددة، ويشجع على توزيع التطبيق داخليًا قبل الإطلاق الكامل. التوثيق الرسمي يذكر إمكانيات مثل internal app sharing، وكذلك إعداد open أو closed أو internal test tracks. الفكرة هنا بسيطة: اجعل خطأك الأول يظهر على يدك أو يد فريقك، لا على جهاز أول مستخدم حقيقي.
الاختبار الداخلي مناسب جدًا عندما تكون تريد شيئًا سريعًا جدًا بينك وبين فريقك. الاختبار المغلق يناسب مجموعة محددة من المختبرين الخارجيين. أما الإنتاج production فهو المرحلة التي يصبح فيها التطبيق متاحًا للمستخدمين جميعًا وفق إعداداتك. هذه المراحل ليست ديكورًا تنظيميًا، بل جزء من إدارة المخاطر، خصوصًا عندما يكون التطبيق جديدًا أو يحتوي على ميزات حساسة.
النشر التدريجي staged rollout
ليس من الضروري أن تنشر التحديث إلى الجميع دفعة واحدة. Google Play يدعم staged rollout، وهي طريقة تتيح لك رفع نسبة الإتاحة تدريجيًا. التوثيق الرسمي يذكر أنه يمكنك من صفحة Production أو صفحات الاختبار إدارة نسبة الإطلاق، وإيقافه أو استئنافه حسب الحاجة. هذه ميزة قوية جدًا، خاصة إذا كنت تخشى من مشاكل تظهر فقط تحت ضغط المستخدمين الحقيقيين.
هذا الأسلوب يريح الأعصاب أيضًا. بدل أن ترى 100% من المستخدمين يحصلون على النسخة الجديدة فورًا، يمكنك البدء بنسبة صغيرة ثم زيادة النسبة عندما تتأكد أن كل شيء مستقر. لو ظهر خطأ حرج، يمكنك إيقاف rollout بسرعة من واجهة Play Console. هذا ليس ضعفًا في الإطلاق، بل احتراف في إدارة الإصدار.
أكثر الأخطاء شيوعًا عند نشر Flutter على Google Play
أول خطأ شائع هو نسيان زيادة رقم النسخة. ستبني النسخة الجديدة، ترفعها، ثم تُفاجأ بأن Play Console يرفضها لأن versionCode لم يتغير. هذا من أكثر الأخطاء التي تتكرر، والتوثيق الرسمي يذكر بوضوح أن التحديث يتطلب زيادة version code ثم إعادة البناء والرفع.
الخطأ الثاني هو التعامل مع keystore كأنه ملف عادي. لا تضعه في Git، ولا ترسله في محادثة، ولا تحتفظ به في مكان غير محمي. Flutter وAndroid يلفتان الانتباه إلى أهمية حماية keystore وملفات التوقيع لأن فقدانها أو تسريبها قد يسبب مشاكل كبيرة، خصوصًا إذا كنت تدير تحديثات لاحقة للتطبيق.
الخطأ الثالث هو تجاهل Play App Signing أو الاعتقاد أنه اختياري في كل الحالات. Android وGoogle Play يوضّحان أن app bundles تعتمد على توقيع الرفع ثم تتولى Google التوقيع النهائي، وأن الانضمام إلى Play App Signing هو المسار الطبيعي والموصى به للتطبيقات الجديدة.
الخطأ الرابع هو رفع تطبيق بلا إعدادات متجر مكتملة. أحيانًا يكون الملف الفني سليمًا، لكن التطبيق يظل مرفوضًا لأن صفحة المتجر أو التصنيف العمري أو الجمهور المستهدف أو السعر أو تفاصيل المحتوى لم تُستكمل. التوثيق الرسمي في Play Console يوضح أن هذه المتطلبات جزء من شرط الإطلاق نفسه.
مثال عملي متكامل من البداية إلى النهاية
لنجعل الصورة أوضح. افترض أن لديك تطبيق Flutter جاهزًا اسمه مثلًا MyShop. الخطوات العملية ستكون تقريبًا بهذا التسلسل: تضبط pubspec.yaml وتراجع version: 1.0.0+1، تنشئ upload-keystore.jks، تربط الملف داخل android/key.properties, تضيف إعدادات التوقيع في Gradle، ثم تبني النسخة النهائية عبر flutter build appbundle. بعد ذلك تفتح Play Console، تنشئ التطبيق، تملأ بيانات المتجر، تكمل التصنيف العمري والمحتوى، ترفع ملف app.aab, تجرب النسخة في internal testing أو closed testing، ثم تنتقل إلى production أو staged rollout. هذا هو المسار العملي الذي تلخصه الوثائق الرسمية من Flutter وGoogle Play وAndroid.
مثال أوامر مختصر:
flutter clean
flutter pub get
flutter build appbundle
وفي حال كنت تريد APK للاختبار المحلي أو التوزيع الخارجي، فFlutter يذكر أيضًا إمكانية بناء APK منفصل، بل ويمكنك استخدام --split-per-abi لإخراج عدة ملفات مخصصة للمعماريات المختلفة. لكن تذكّر أن المتجر نفسه يفضّل AAB للنشر العام.
هل أحتاج إلى APK أصلًا؟
في أغلب حالات النشر إلى Google Play: لا، لا تحتاجه. الأفضل هو AAB. Flutter يضع App Bundle كصيغة مفضلة للنشر على متجر Google Play، وAndroid يشرح أن Google Play يستخدمه لتوليد APKs محسنة لكل جهاز. لذلك، إذا كان هدفك هو المتجر، فركز على AAB. أما APK فيبقى مفيدًا في سيناريوهات مثل تثبيت يدوي على جهاز، أو مشاركة نسخة سريعة للاختبار، أو التوزيع خارج Play Play.
ماذا عن تحسين الحجم والأداء قبل النشر؟
Flutter وAndroid يشيران إلى أهمية تحسين النسخة النهائية قبل النشر. Flutter يذكر R8 لتقليل الكود، وإعداد multidex عند الحاجة، ومراجعة manifest وbuild configuration. كما يوضح أن App Bundle يساعد بطبيعته على تقليل حجم التنزيل لأن Play يقدم فقط الموارد المناسبة للجهاز. لذلك، إذا كان التطبيق كبيرًا، فهذه المرحلة ليست رفاهية، بل فرق حقيقي في تجربة المستخدم الأولى.
لو كان تطبيقك يعتمد على مكتبات كثيرة أو صور وفيديوهات وحزم متعددة، ففكر في التنظيف المبكر: حذف الحزم غير المستخدمة، تصغير الأصول، ضغط الصور، والتأكد من أن كل مكتبة موجودة لسبب واضح. أحيانًا لا يكون سبب البطء أو الثقل في Flutter نفسه، بل في قرارات ضمّنها المشروع على طول الطريق. هذا جزء عملي جدًا من “التحضير للنشر”، حتى وإن لم تذكره الصفحة الرسمية بهذه العبارة الحرفية.
لو واجهتك مشكلة في التوقيع
إذا ظهرت لك رسالة تتعلق بالمفتاح أو التوقيع، فالخطوة الأولى هي التأكد من أنك تستخدم upload key الصحيح، وليس app signing key الخاص بالتوزيع النهائي. توثيق Google Play يفرّق بين key الرفع وkey التوقيع النهائي، ويذكر أيضًا أن بإمكانك رؤية بصمات SHA-1 أو SHA-256 من قسم App signing key داخل Play Console واستخدامها عند الحاجة مع بعض مزودي الخدمات مثل Google Cloud أو Android App Links.
وعندما يكون المشروع قديمًا أو تم نقله بين فرق، قد تحتاج إلى إدارة المفاتيح بعناية أكبر أو حتى نقلها. لهذا السبب أنصح دائمًا بأن تحتفظ بنسخة آمنة جدًا من الملفات والمعلومات المتعلقة بالتوقيع من اليوم الأول. فقدانها ليس أمرًا بسيطًا، لأن التوقيع هو الهوية المستمرة للتطبيق عبر التحديثات.
لو واجهتك مشكلة في الرفض أثناء المراجعة
الرفض لا يعني بالضرورة أن التطبيق سيئ، لكنه يعني أن هناك نقطة لا تتوافق مع متطلبات Google Play. قد تكون المشكلة في صفحة المتجر، أو في content rating، أو في target audience، أو في محتوى التطبيق، أو في سياسة الخصوصية، أو في قيمة لم تُحدث داخل الإصدار. التوثيق الرسمي يشير إلى أن Google تراجع هذه البيانات، وأن عدم الدقة قد يسبب الإزالة أو التعليق أو الرفض. لذلك، عند ظهور الرفض، لا تتعامل معه كحكم نهائي، بل كمراجعة دقيقة تحتاج إلى إصلاح موضوعي.
متى أستخدم التحديثات المستمرة CI/CD؟
إذا كنت تنشر أكثر من تطبيق، أو إذا كان فريقك يعمل باستمرار على نسخ متعددة، فالتوثيق الخاص بـ Flutter يوصي بممارسات Continuous Delivery حتى تصل التحديثات إلى المختبرين بشكل متكرر وبدون إجراءات يدوية مرهقة. هذا لا يعني أنك ملزم بإعداد CI/CD من اليوم الأول، لكنه يصبح مفيدًا جدًا عندما يبدأ التطبيق بالنمو وتصبح عملية الإصدار متكررة.
عمليًا، CI/CD يساعدك على أتمتة البناء، التوقيع، رفع النسخ إلى قنوات الاختبار، وأحيانًا حتى إدارة الإطلاق التدريجي. وعندما يصبح التطبيق منتجًا حقيقيًا، ستدرك أن أتمتة هذه التفاصيل ليست رفاهية، بل وسيلة لتقليل الأخطاء البشرية في كل نسخة جديدة.
قائمة مراجعة أخيرة قبل الضغط على زر النشر
قبل أن ترفع التطبيق النهائي، تأكد من الآتي: التطبيق يعمل في release، ملف AAB تم إنشاؤه بنجاح، التوقيع مضبوط، رقم الإصدار محدث، صفحة المتجر مكتملة، التصنيف العمري والجمهور المستهدف صحيحان، وسياسة الخصوصية موجودة إذا لزم الأمر. هذه النقاط ليست ثانوية، بل هي ما يجعل النشر سلسًا بدل أن يتحول إلى سلسلة من الأخطاء المتفرقة. هذا بالضبط ما تعكسه الوثائق الرسمية عبر توزيعها للخطوات بين Flutter build/release وPlay Console setup وapp content وPlay App Signing.
خاتمة
نشر تطبيق Flutter على Google Play يبدو طويلًا في البداية، لكنه يصبح طبيعيًا جدًا عندما تفهم الفكرة العامة: جهّز التطبيق جيدًا، وقّعه بشكل صحيح، ابنِ AAB بدل APK للنشر العام، ارفع النسخة إلى Play Console، أكمل بيانات المتجر والمحتوى، ثم اختبر قبل أن توسّع الإتاحة. عندما تتعامل مع الخطوات بهذه الطريقة، ستجد أن العملية ليست مخيفة كما تبدو، بل منظمة وواضحة ويمكن تكرارها في كل تحديث جديد. Flutter وGoogle Play وAndroid كلها تلتقي عند هذه القاعدة: لا تجعل آخر خطوة هي أول مرة تفكر فيها بجدية في النشر.