استخدام حِزم تطوير البرامج (SDK) لنظام التشغيل Android التي تم إنشاؤها

تتيح لك حِزم تطوير البرامج (SDK) للعميل Firebase SQL Connect استدعاء طلبات البحث والتعديلات من جهة الخادم مباشرةً من تطبيق Firebase. يمكنك إنشاء حزمة تطوير برامج (SDK) مخصّصة للعميل بالتوازي مع تصميم المخططات وطلبات البحث والتعديلات التي تنشرها في خدمتك SQL Connect. بعد ذلك، يمكنك دمج طرق من حزمة تطوير البرامج (SDK) هذه في منطق العميل.

كما ذكرنا في مكان آخر، من المهم ملاحظة أنّه لا يتم إرسال SQL Connect طلبات البحث والتعديلات من خلال رمز العميل وتنفيذها على الخادم. بدلاً من ذلك، عند نشرها، يتم تخزين عمليات SQL Connect على الخادم مثل Cloud Functions. وهذا يعني أنّه عليك نشر التغييرات المقابلة من جهة العميل لتجنُّب تعطُّل التطبيق لدى المستخدمين الحاليين (مثلاً، على إصدارات التطبيق القديمة).

لهذا السبب، يوفّر لك SQL Connect بيئة تطوير و أدوات تتيح لك إنشاء نماذج أولية للمخططات وطلبات البحث والتعديلات التي تنشرها على الخادم. كما أنّه ينشئ حِزم تطوير البرامج (SDK) من جهة العميل تلقائيًا أثناء إنشاء النماذج الأولية.

بعد إجراء تعديلات متكرّرة على خدمتك وتطبيقات العميل، يصبح بإمكانك نشر التعديلات من جهة الخادم والعميل.

ما هي آلية تطوير العميل؟

إذا اتّبعت الخطوات الواردة في مقالة البدء، تعرّفت على آلية التطوير العامة في SQL Connect. في هذا الدليل، ستجد معلومات أكثر تفصيلاً حول إنشاء حِزم تطوير البرامج (SDK) لنظام التشغيل Android من المخطط واستخدام طلبات البحث والتعديلات من جهة العميل.

باختصار، لاستخدام حِزم تطوير البرامج (SDK) التي تم إنشاؤها لنظام التشغيل Android في تطبيقات العميل، عليك اتّباع الخطوات الأساسية التالية:

  1. أضِف Firebase إلى تطبيق Android.
  2. اضبط SQL Connect كاعتمادية في Gradle.
  3. أضِف مكوّن Gradle الإضافي Kotlin Serialization واعتمادية Gradle.

بعد ذلك:

  1. طوِّر مخطط تطبيقك.
  2. اضبط عملية إنشاء حزمة تطوير البرامج (SDK):

    • باستخدام الزر إضافة حزمة تطوير البرامج (SDK) إلى التطبيق في إضافة SQL Connect لبرنامج VS Code
    • من خلال تعديل connector.yaml
  3. ابدأ رمز العميل واستورِد المكتبات.

  4. نفِّذ عمليات استدعاء لطلبات البحث والتعديلات.

  5. اضبط محاكي SQL Connect واستخدِمه، ثم كرِّر العملية.

إنشاء حزمة تطوير البرامج (SDK) بلغة Kotlin

استخدِم واجهة سطر الأوامر في Firebase لإعداد حِزم تطوير البرامج (SDK) التي تم إنشاؤها في SQL Connect في تطبيقاتك. يجب أن يرصد الأمر init جميع التطبيقات في المجلد الحالي وأن يثبِّت حِزم تطوير البرامج (SDK) التي تم إنشاؤها تلقائيًا.

firebase init dataconnect:sdk

تعديل حِزم تطوير البرامج (SDK) أثناء إنشاء النماذج الأولية

إذا كانت إضافة SQL Connect لبرنامج VS Code مثبّتة، ستحرص دائمًا على أن تكون حِزم تطوير البرامج (SDK) التي تم إنشاؤها حديثة.

إذا كنت لا تستخدم إضافة SQL Connect لبرنامج VS Code، يمكنك استخدام Firebase CLI للحفاظ على حِزم تطوير البرامج (SDK) التي تم إنشاؤها حديثة.

firebase dataconnect:sdk:generate --watch

إنشاء حِزم تطوير البرامج (SDK) في مسارات الإصدار

يمكنك استخدام Firebase CLI لإنشاء حِزم تطوير البرامج (SDK) SQL Connect في عمليات الإصدار المتواصل والتسليم المتواصل (CI/CD).

firebase dataconnect:sdk:generate

إعداد رمز العميل

دمج SQL Connect في رمز العميل

لإعداد رمز العميل لاستخدام SQL Connect وحزمة تطوير البرامج (SDK) التي تم إنشاؤها، اتّبِع أولاً تعليمات الإعداد العادية في Firebase.

بعد ذلك، أضِف ما يلي إلى قسم plugins في app/build.gradle.kts:

// The Firebase team tests with version 1.8.22; however, other 1.8 versions,
// and all newer versions are expected work too.
kotlin("plugin.serialization") version "1.8.22" // MUST match the version of the Kotlin compiler

بعد ذلك، أضِف ما يلي إلى قسم dependencies في app/build.gradle.kts:

implementation(platform("com.google.firebase:firebase-bom:34.13.0"))
implementation("com.google.firebase:firebase-dataconnect")
implementation("com.google.firebase:firebase-auth") // Optional
implementation("com.google.firebase:firebase-appcheck") // Optional
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") // Newer versions should work too
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.5.1") // Newer versions should work too

بدء حزمة تطوير البرامج (SDK) لنظام التشغيل Android في SQL Connect

ابدأ مثيل SQL Connect باستخدام المعلومات التي استخدمتها لإعداد SQL Connect. يمكنك العثور على هذه المعلومات في قواعد البيانات ومساحة التخزين > SQL Connect صفحة في وحدة تحكُّم Firebase.

الكائن ConnectorConfig

تتطلّب حزمة تطوير البرامج (SDK) كائن إعدادات الموصّل.

يتم إنشاء هذا الكائن تلقائيًا من serviceId وlocation في dataconnect.yaml وconnectorId في connector.yaml.

الحصول على مثيل موصّل

بعد إعداد كائن إعدادات، احصل على مثيل موصّل SQL Connect. سينشئ محاكي SQL Connect الرمز البرمجي للموصّل. إذا كان اسم الموصّل هو movies وحزمة Kotlin هي com.myapplication، كما هو محدّد في connector.yaml، يمكنك استرداد كائن الموصّل من خلال استدعاء:

val connector = com.myapplication.MoviesConnector.instance

استخدام طلبات البحث والتعديلات من حزمة تطوير البرامج (SDK) لنظام التشغيل Android

باستخدام كائن الموصّل، يمكنك تشغيل طلبات البحث والتعديلات كما هو محدّد في رمز GraphQL المصدر. لنفترض أنّ الموصّل يتضمّن العمليات التالية:

mutation createMovie($title: String!, $releaseYear: Int!, $genre: String!, $rating: Int!) {
  movie_insert(data: {
    title: $title
    releaseYear: $releaseYear
    genre: $genre
    rating: $rating
  })
}

query getMovieByKey($key: Movie_Key!) {
  movie(key: $key) { id title }
}

query listMoviesByGenre($genre: String!) {
  movies(where: {genre: {eq: $genre}}) {
    id
    title
  }
}

يمكنك بعد ذلك إنشاء فيلم واسترداده على النحو التالي:

val connector = MoviesConnector.instance

val addMovieResult1 = connector.createMovie.execute(
  title = "Empire Strikes Back",
  releaseYear = 1980,
  genre = "Sci-Fi",
  rating = 5
)

val movie1 = connector.getMovieByKey.execute(addMovieResult1.data.key)

println("Empire Strikes Back: ${movie1.data.movie}")

يمكنك أيضًا استرداد أفلام متعددة:

val connector = MoviesConnector.instance

val addMovieResult2 = connector.createMovie.execute(
  title="Attack of the Clones",
  releaseYear = 2002,
  genre = "Sci-Fi",
  rating = 5
)

val listMoviesResult = connector.listMoviesByGenre.execute(genre = "Sci-Fi")

println(listMoviesResult.data.movies)

يمكنك أيضًا جمع Flow لن يعرض نتيجة إلا عند استرداد نتيجة طلب بحث جديدة باستخدام استدعاء طريقة execute() لطلب البحث.

val connector = MoviesConnector.instance

connector.listMoviesByGenre.flow(genre = "Sci-Fi").collect { data ->
  println(data.movies)
}

connector.createMovie.execute(
  title="A New Hope",
  releaseYear = 1977,
  genre = "Sci-Fi",
  rating = 5
)

connector.listMoviesByGenre.execute(genre = "Sci-Fi") // will cause the Flow to get notified

التعامل مع التغييرات في حقول التعداد

يمكن أن يحتوي مخطط التطبيق على عمليات تعداد، يمكن الوصول إليها من خلال طلبات بحث GraphQL.

مع تغيُّر تصميم التطبيق، قد تضيف قيمًا جديدة متوافقة مع التعداد. على سبيل المثال، لنفترض أنّك قرّرت لاحقًا في دورة حياة تطبيقك إضافة قيمة FULLSCREEN إلى التعداد AspectRatio.

في آلية عمل SQL Connect، يمكنك استخدام أدوات التطوير المحلية لـ تعديل طلبات البحث وحِزم تطوير البرامج (SDK).

ومع ذلك، قبل إطلاق إصدار معدّل من تطبيقات العميل، قد تتعطّل تطبيقات العميل القديمة التي تم نشرها.

مثال على التنفيذ المرن

تفرض حزمة تطوير البرامج (SDK) التي تم إنشاؤها التعامل مع القيم غير المعروفة لأنّ رمز العميل يجب أن يزيل تغليف الكائن EnumValue، الذي يكون إما EnumValue.Known لقيم التعداد المعروفة أو EnumValue.Unknown للقيم غير المعروفة.

val result = connector.listMoviesByAspectRatio.execute(AspectRatio.WIDESCREEN)
val encounteredAspectRatios = mutableSetOf<String>()

result.data.movies
  .mapNotNull { it.otherAspectRatios }
  .forEach { otherAspectRatios ->
    otherAspectRatios
      .filterNot { it.value == AspectRatio.WIDESCREEN }
      .forEach {
        when (it) {
          is EnumValue.Known -> encounteredAspectRatios.add(it.value.name)
          is EnumValue.Unknown ->
            encounteredAspectRatios.add("[unknown ratio: ${it.stringValue}]")
        }
      }
  }

println(
  "Widescreen movies also include additional aspect ratios: " +
    encounteredAspectRatios.sorted().joinToString()
)

تفعيل التخزين المؤقت من جهة العميل

يتضمّن SQL Connect ميزة اختيارية للتخزين المؤقت من جهة العميل، يمكنك تفعيلها من خلال تعديل ملف connector.yaml. عند تفعيل هذه الميزة، ستخزّن حِزم تطوير البرامج (SDK) التي تم إنشاؤها من جهة العميل ردود طلبات البحث محليًا، ما يمكن أن يقلّل عدد طلبات قاعدة البيانات التي يرسلها تطبيقك ويسمح لأجزاء التطبيق التي تعتمد على قاعدة البيانات بالعمل عند انقطاع الشبكة.

لتفعيل التخزين المؤقت من جهة العميل، أضِف إعدادات التخزين المؤقت من جهة العميل إلى إعدادات الموصّل:

generate:
  kotlinSdk:
    outputDir: "../android"
    package: "com.google.firebase.dataconnect.generated"
    clientCache:
      maxAge: 5s
      storage: persistent

يتضمّن هذا الإعداد مَعلمتَين، وكلاهما اختياري:

  • maxAge: الحد الأقصى لعمر الردّ المخزّن مؤقتًا قبل أن تجلب حزمة تطوير البرامج (SDK) من جهة العميل قيمًا جديدة. أمثلة: "0" و"30s" و"1h30m"

    القيمة التلقائية لـ maxAge هي 0، ما يعني أنّه يتم تخزين الردود مؤقتًا، ولكن ستجلب حزمة تطوير البرامج (SDK) من جهة العميل دائمًا قيمًا جديدة. لن يتم استخدام القيم المخزّنة مؤقتًا إلا إذا تم تحديد CACHE_ONLY لـ execute().

  • storage: يمكن ضبط حزمة تطوير البرامج (SDK) من جهة العميل لتخزين الردود مؤقتًا إما في مساحة التخزين persistent أو في memory. ستبقى النتائج المخزّنة مؤقتًا في مساحة التخزين persistent بعد إعادة تشغيل التطبيق. في حِزم تطوير البرامج (SDK) لنظام التشغيل Android، تكون القيمة التلقائية هي persistent.

بعد تعديل إعدادات التخزين المؤقت للموصّل، أعِد إنشاء حِزم تطوير البرامج (SDK) من جهة العميل وأعِد إنشاء تطبيقك. بعد إجراء ذلك، سيخزّن execute() الردود مؤقتًا ويستخدم القيم المخزّنة مؤقتًا وفقًا للسياسة التي ضبطتها. يحدث هذا تلقائيًا بشكل عام، بدون أي خطوات إضافية من جانبك، ولكن يُرجى العِلم بما يلي:

  • يكون السلوك التلقائي لـ execute() كما هو موضّح أعلاه: إذا تم تخزين نتيجة مؤقتًا لطلب بحث ولم تكن القيمة المخزّنة مؤقتًا أقدم من maxAge، يتم استخدام القيمة المخزّنة مؤقتًا. يُعرف هذا السلوك التلقائي باسم سياسة PREFER_CACHE.

    يمكنك أيضًا تحديد عمليات استدعاء فردية لـ execute() لعرض القيم المخزّنة مؤقتًا فقط (CACHE_ONLY) أو لجلب قيم جديدة من الخادم بدون شروط (SERVER_ONLY).

    val queryResult = queryRef.execute(QueryRef.FetchPolicy.CACHE_ONLY)
    
    val queryResult = queryRef.execute(QueryRef.FetchPolicy.SERVER_ONLY)
    

    إنشاء نموذج أولي لتطبيق Android واختباره

    إعداد تطبيقات العميل لاستخدام محاكي محلي

    يمكنك استخدام محاكي SQL Connect، سواء من إضافة SQL Connect لبرنامج VS Code أو من واجهة سطر الأوامر.

    إنّ إعداد التطبيق للاتصال بالمحاكي هو نفسه في كلتا الحالتَين.

    val connector = MoviesConnector.instance
    
    // Connect to the emulator on "10.0.2.2:9399"
    connector.dataConnect.useEmulator()
    
    // (alternatively) if you're running your emulator on non-default port:
    connector.dataConnect.useEmulator(port = 9999)
    
    // Make calls from your app
    
    

    للتبديل إلى موارد الإنتاج، علِّق على الأسطر الخاصة بالاتصال بالمحاكي.

    أنواع SQL في حِزم تطوير البرامج (SDK) في SQL Connect

    يمثّل خادم SQL Connect أنواع بيانات GraphQL الشائعة والمخصّصة. ويتم تمثيلها في حزمة تطوير البرامج (SDK) على النحو التالي.

    نوع SQL Connect Kotlin
    سلسلة سلسلة
    Int Int (عدد صحيح 32 بت)
    عائم Double (قيمة عددية عائمة 64 بت)
    قيمة منطقية قيمة منطقية
    معرِّف فريد عالمي (UUID) java.util.UUID
    التاريخ com.google.firebase.dataconnect.LocalDate (كان java.util.Date حتى الإصدار 16.0.0-beta03)
    الطابع الزمني com.google.firebase.Timestamp
    Int64 طويلة
    أي com.google.firebase.dataconnect.AnyValue