Google is committed to advancing racial equity for Black communities. See how.
ترجمت واجهة Cloud Translation API‏ هذه الصفحة.
Switch to English

قم بترحيل تطبيق Android Parse إلى Firebase

إذا كنت من مستخدمي Parse وتبحث عن خلفية بديلة كحل خدمة ، فقد يكون Firebase الخيار المثالي لتطبيق Android.

يصف هذا الدليل كيفية دمج خدمات معينة في تطبيقك. للحصول على تعليمات إعداد Firebase الأساسية ، راجع دليل إعداد Android .

تحليلات كوكل

Google Analytics هو حل مجاني لقياس التطبيق يوفر نظرة ثاقبة حول استخدام التطبيق ومشاركة المستخدم. يتكامل Analytics عبر ميزات Firebase ويوفر لك تقارير غير محدودة لما يصل إلى 500 حدث مميز يمكنك تحديده باستخدام Firebase SDK.

راجع مستندات Google Analytics لمعرفة المزيد.

استراتيجية الهجرة المقترحة

يعد استخدام موفري التحليلات المختلفين سيناريو شائع ينطبق بسهولة على Google Analytics. ما عليك سوى إضافته إلى تطبيقك للاستفادة من الأحداث وخصائص المستخدم التي يجمعها Analytics تلقائيًا ، مثل الفتح الأول وتحديث التطبيق وطراز الجهاز والعمر.

بالنسبة إلى الأحداث المخصصة وخصائص المستخدم ، يمكنك استخدام استراتيجية كتابة مزدوجة باستخدام كل من Parse Analytics و Google Analytics لتسجيل الأحداث والمواقع ، مما يتيح لك طرح الحل الجديد تدريجيًا.

مقارنة الكود

تحليل التحليلات

 // Start collecting data
ParseAnalytics.trackAppOpenedInBackground(getIntent());

Map<String, String> dimensions = new HashMap<String, String>();
// Define ranges to bucket data points into meaningful segments
dimensions.put("priceRange", "1000-1500");
// Did the user filter the query?
dimensions.put("source", "craigslist");
// Do searches happen more often on weekdays or weekends?
dimensions.put("dayType", "weekday");

// Send the dimensions to Parse along with the 'search' event
ParseAnalytics.trackEvent("search", dimensions);
 

تحليلات كوكل

 // Obtain the FirebaseAnalytics instance and start collecting data
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);

Bundle params = new Bundle();
// Define ranges to bucket data points into meaningful segments
params.putString("priceRange", "1000-1500");
// Did the user filter the query?
params.putString("source", "craigslist");
// Do searches happen more often on weekdays or weekends?
params.putString("dayType", "weekday");

// Send the event
mFirebaseAnalytics.logEvent("search", params);
 

قاعدة بيانات Firebase في الوقت الحقيقي

قاعدة بيانات Firebase Realtime هي قاعدة بيانات مستضافة على السحابة الإلكترونية NoSQL. يتم تخزين البيانات بتنسيق JSON ومزامنتها في الوقت الفعلي مع كل عميل متصل.

راجع مستندات Firebase Realtime Database لمعرفة المزيد.

الفروق مع بيانات التحليل

شاء

في ParseObject ، تقوم بتخزين ParseObject ، أو فئة فرعية منه ، تحتوي على أزواج القيمة الرئيسية للبيانات المتوافقة مع JSON. البيانات غير مخطط لها ، مما يعني أنك لست بحاجة إلى تحديد المفاتيح الموجودة في كل ParseObject .

يتم تخزين جميع بيانات Firebase Realtime Database ككائنات JSON ، ولا يوجد مكافئ لـ ParseObject ؛ تكتب ببساطة إلى قيم شجرة JSON للأنواع التي تتوافق مع أنواع JSON المتاحة. يمكنك استخدام كائنات Java لتبسيط القراءة والكتابة من قاعدة البيانات.

فيما يلي مثال لكيفية حفظ النتائج العالية للعبة.

تحليل
 @ParseClassName("GameScore")
public class GameScore {
        public GameScore() {}
        public GameScore(Long score, String playerName, Boolean cheatMode) {
            setScore(score);
            setPlayerName(playerName);
            setCheatMode(cheatMode);
        }

        public void setScore(Long score) {
            set("score", score);
        }

        public Long getScore() {
            return getLong("score");
        }

        public void setPlayerName(String playerName) {
            set("playerName", playerName);
        }

        public String getPlayerName() {
            return getString("playerName");
        }

        public void setCheatMode(Boolean cheatMode) {
            return set("cheatMode", cheatMode);
        }

        public Boolean getCheatMode() {
            return getBoolean("cheatMode");
        }
}

// Must call Parse.registerSubclass(GameScore.class) in Application.onCreate
GameScore gameScore = new GameScore(1337, "Sean Plott", false);
gameScore.saveInBackground();
 
Firebase
 // Assuming we defined the GameScore class as:
public class GameScore {
        private Long score;
        private String playerName;
        private Boolean cheatMode;

        public GameScore() {}
        public GameScore(Long score, String playerName, Boolean cheatMode) {
            this.score = score;
            this.playerName = playerName;
            this.cheatMode = cheatMode;
        }

        public Long getScore() {
            return score;
        }

        public String getPlayerName() {
            return playerName;
        }

        public Boolean getCheatMode() {
            return cheatMode;
        }
}

// We would save it to our list of high scores as follows:
DatabaseReference mFirebaseRef = FirebaseDatabase.getInstance().getReference();
GameScore score = new GameScore(1337, "Sean Plott", false);
mFirebaseRef.child("scores").push().setValue(score);
 
لمزيد من التفاصيل ، راجع دليل قراءة وكتابة البيانات على Android .

العلاقات بين البيانات

يمكن أن يكون ل ParseObject علاقة مع ParseObject آخر: يمكن لأي كائن استخدام كائنات أخرى كقيم.

في قاعدة بيانات Firebase Realtime ، يتم التعبير عن العلاقات بشكل أفضل باستخدام هياكل البيانات المسطحة التي تقسم البيانات إلى مسارات منفصلة ، بحيث يمكن تنزيلها بكفاءة في مكالمات منفصلة.

فيما يلي مثال على كيفية بناء العلاقة بين المنشورات في تطبيق التدوين ومؤلفيها.

تحليل
 // Create the author
ParseObject myAuthor = new ParseObject("Author");
myAuthor.put("name", "Grace Hopper");
myAuthor.put("birthDate", "December 9, 1906");
myAuthor.put("nickname", "Amazing Grace");

// Create the post
ParseObject myPost = new ParseObject("Post");
myPost.put("title", "Announcing COBOL, a New Programming Language");

// Add a relation between the Post and the Author
myPost.put("parent", myAuthor);

// This will save both myAuthor and myPost
myPost.saveInBackground();
 
Firebase
 DatabaseReference firebaseRef = FirebaseDatabase.getInstance().getReference();
// Create the author
Map<String, String> myAuthor = new HashMap<String, String>();
myAuthor.put("name", "Grace Hopper");
myAuthor.put("birthDate", "December 9, 1906");
myAuthor.put("nickname", "Amazing Grace");

// Save the author
String myAuthorKey = "ghopper";
firebaseRef.child('authors').child(myAuthorKey).setValue(myAuthor);

// Create the post
Map<String, String> post = new HashMap<String, String>();
post.put("author", myAuthorKey);
post.put("title", "Announcing COBOL, a New Programming Language");
firebaseRef.child('posts').push().setValue(post);
 

مخطط البيانات التالي هو النتيجة.

{
  // Info about the authors
  "authors": {
    "ghopper": {
      "name": "Grace Hopper",
      "date_of_birth": "December 9, 1906",
      "nickname": "Amazing Grace"
    },
    ...
  },
  // Info about the posts: the "author" fields contains the key for the author
  "posts": {
    "-JRHTHaIs-jNPLXOQivY": {
      "author": "ghopper",
      "title": "Announcing COBOL, a New Programming Language"
    }
    ...
  }
}
لمزيد من التفاصيل ، راجع دليل بنية قاعدة البيانات الخاصة بك .

قراءة البيانات

في Parse ، تقرأ البيانات باستخدام إما معرف كائن ParseQuery معين ، أو تنفيذ الاستعلامات باستخدام ParseQuery .

في Firebase ، يمكنك استرداد البيانات عن طريق إرفاق مستمع غير متزامن إلى مرجع قاعدة بيانات. يتم تشغيل المستمع مرة واحدة للحالة الأولية للبيانات ومرة ​​أخرى عندما تتغير البيانات ، لذلك لن تحتاج إلى إضافة أي رمز لتحديد ما إذا كانت البيانات قد تغيرت.

فيما يلي مثال لكيفية استرداد النقاط للاعب معين ، بناءً على المثال المقدم في قسم "الكائنات" .

تحليل
 ParseQuery<ParseObject> query = ParseQuery.getQuery("GameScore");
query.whereEqualTo("playerName", "Dan Stemkoski");
query.findInBackground(new FindCallback<ParseObject>() {
    public void done(List<ParseObject> scoreList, ParseException e) {
        if (e == null) {
            for (ParseObject score: scoreList) {
                Log.d("score", "Retrieved: " + Long.toString(score.getLong("score")));
            }
        } else {
            Log.d("score", "Error: " + e.getMessage());
        }
    }
});
 
Firebase
 DatabaseReference mFirebaseRef = FirebaseDatabase.getInstance().getReference();
Query mQueryRef = mFirebaseRef.child("scores").orderByChild("playerName").equalTo("Dan Stemkoski");

// This type of listener is not one time, and you need to cancel it to stop
// receiving updates.
mQueryRef.addChildEventListener(new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot snapshot, String previousChild) {
        // This will fire for each matching child node.
        GameScore score = snapshot.getValue(GameScore.class);
        Log.d("score", "Retrieved: " + Long.toString(score.getScore());
    }
});
 
لمزيد من التفاصيل حول الأنواع المتاحة من مستمعي الأحداث وكيفية طلب البيانات وتصفيتها ، راجع دليل القراءة والكتابة على Android .

استراتيجية الهجرة المقترحة

أعد التفكير في بياناتك

تم تحسين قاعدة بيانات Firebase Realtime لمزامنة البيانات بالمللي ثانية عبر جميع العملاء المتصلين ، وهيكل البيانات الناتج يختلف عن بيانات التحليل الأساسية. وهذا يعني أن الخطوة الأولى لعملية الترحيل هي مراعاة التغييرات التي تتطلبها بياناتك ، بما في ذلك:

  • كيفية تعيين كائنات "التحليل" لبيانات Firebase
  • إذا كانت لديك علاقات بين الوالدين والطفل ، فكيف يمكنك تقسيم بياناتك عبر مسارات مختلفة بحيث يمكن تنزيلها بكفاءة في مكالمات منفصلة.

ترحيل بياناتك

بعد أن تقرر كيفية تنظيم بياناتك في Firebase ، تحتاج إلى التخطيط لكيفية التعامل مع الفترة التي يحتاج تطبيقك خلالها إلى الكتابة إلى قاعدتي البيانات. اختياراتك هي:

مزامنة الخلفية

في هذا السيناريو ، لديك إصداران من التطبيق: الإصدار القديم الذي يستخدم Parse ونسخة جديدة تستخدم Firebase. تتم معالجة المزامنات بين قاعدتي البيانات بواسطة Parse Cloud Code (Parse to Firebase) ، مع الاستماع إلى التغييرات في Firebase ومزامنة هذه التغييرات مع Parse. قبل أن تتمكن من البدء في استخدام الإصدار الجديد ، يجب عليك:

  • حوّل بياناتك الحالية إلى بنية Firebase الجديدة ، واكتبها في Firebase Realtime Database.
  • اكتب وظائف Parse Cloud Code التي تستخدم Firebase REST API للكتابة إلى تغييرات قاعدة بيانات Realbase Realtime التي تم إجراؤها في بيانات التحليل بواسطة العملاء القدامى.
  • اكتب ونشر التعليمات البرمجية التي تستمع إلى التغييرات في Firebase وتزامنها مع قاعدة بيانات التحليل.

يضمن هذا السيناريو فصلًا نظيفًا بين التعليمات البرمجية القديمة والجديدة ، ويبقي العملاء بسيطًا. تتمثل تحديات هذا السيناريو في معالجة مجموعات البيانات الكبيرة في التصدير الأولي ، والتأكد من أن المزامنة ثنائية الاتجاه لا تؤدي إلى تكرار لا نهائي.

كتابة مزدوجة

في هذا السيناريو ، تكتب إصدارًا جديدًا من التطبيق يستخدم كلاً من Firebase و Parse ، باستخدام Parse Cloud Code لمزامنة التغييرات التي أجراها العملاء القدامى من Parse Data إلى قاعدة بيانات Firebase Realtime. عندما يقوم عدد كافٍ من الأشخاص بالترحيل من إصدار Parse-only من التطبيق ، يمكنك إزالة رمز Parse من إصدار الكتابة المزدوج.

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

مصادقة Firebase

يمكن لمصادقة Firebase مصادقة المستخدمين باستخدام كلمات المرور ومزودي الهويات الموحدة الشهيرة مثل Google و Facebook و Twitter. كما يوفر مكتبات UI لتوفير الاستثمار الهام المطلوب لتنفيذ والحفاظ على تجربة مصادقة كاملة لتطبيقك عبر جميع الأنظمة الأساسية.

راجع مستندات مصادقة Firebase لمعرفة المزيد.

الاختلافات مع تحليل المصادقة

يوفر ParseUser فئة مستخدم متخصصة تسمى ParseUser تتعامل تلقائيًا مع الوظائف المطلوبة لإدارة حساب المستخدم. ParseUser هو فئة فرعية من ParseObject ، مما يعني أن بيانات المستخدم متاحة في بيانات ParseObject ويمكن توسيعها مع حقول إضافية مثل أي ParseObject أخرى.

يحتوي FirebaseUser على مجموعة ثابتة من الخصائص الأساسية - معرف فريد ، وعنوان بريد إلكتروني أساسي ، واسم وعنوان URL للصورة - مخزنة في قاعدة بيانات مستخدم مشروع منفصل ؛ يمكن تحديث هذه الخصائص من قبل المستخدم. لا يمكنك إضافة خصائص أخرى إلى كائن FirebaseUser مباشرة ؛ بدلاً من ذلك ، يمكنك تخزين الخصائص الإضافية في Firebase Realtime Database.

فيما يلي مثال لكيفية تسجيل مستخدم وإضافة حقل رقم هاتف إضافي.

تحليل
 ParseUser user = new ParseUser();
user.setUsername("my name");
user.setPassword("my pass");
user.setEmail("email@example.com");

// other fields can be set just like with ParseObject
user.put("phone", "650-253-0000");

user.signUpInBackground(new SignUpCallback() {
    public void done(ParseException e) {
        if (e == null) {
            // Hooray! Let them use the app now.
        } else {
            // Sign up didn't succeed. Look at the ParseException
            // to figure out what went wrong
        }
    }
});
 
Firebase
 FirebaseAuth mAuth = FirebaseAuth.getInstance();

mAuth.createUserWithEmailAndPassword("email@example.com", "my pass")
    .continueWithTask(new Continuation<AuthResult, Task<Void>> {
        @Override
        public Task<Void> then(Task<AuthResult> task) {
            if (task.isSuccessful()) {
                FirebaseUser user = task.getResult().getUser();
                DatabaseReference firebaseRef = FirebaseDatabase.getInstance().getReference();
                return firebaseRef.child("users").child(user.getUid()).child("phone").setValue("650-253-0000");
            } else {
                // User creation didn't succeed. Look at the task exception
                // to figure out what went wrong
                Log.w(TAG, "signInWithEmail", task.getException());
            }
        }
    });
 

استراتيجية الهجرة المقترحة

ترحيل الحسابات

لترحيل حسابات المستخدمين من Parse إلى Firebase ، قم بتصدير قاعدة بيانات المستخدم إلى ملف JSON أو CSV ، ثم قم باستيراد الملف إلى مشروع Firebase باستخدام auth:import Firebase CLI auth:import .

أولاً ، قم بتصدير قاعدة بيانات المستخدم الخاصة بك من وحدة تحكم Parse أو قاعدة البيانات ذاتية الاستضافة. على سبيل المثال ، قد يبدو ملف JSON الذي تم تصديره من وحدة تحكم Parse كما يلي:

{ // Username/password user
  "bcryptPassword": "$2a$10$OBp2hxB7TaYZgKyTiY48luawlTuYAU6BqzxJfpHoJMdZmjaF4HFh6",
  "email": "user@example.com",
  "username": "testuser",
  "objectId": "abcde1234",
  ...
},
{ // Facebook user
  "authData": {
    "facebook": {
      "access_token": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
      "expiration_date": "2017-01-02T03:04:05.006Z",
      "id": "1000000000"
    }
  },
  "username": "wXyZ987654321StUv",
  "objectId": "fghij5678",
  ...
}

بعد ذلك ، قم بتحويل الملف الذي تم تصديره إلى التنسيق المطلوب بواسطة Firebase CLI. استخدم objectId لمستخدمي localId لديك localId لمستخدمي localId . أيضا ، ترميز base64 قيم bcryptPassword من bcryptPassword وتستخدمها في حقل passwordHash . فمثلا:

{
  "users": [
    {
      "localId": "abcde1234",  // Parse objectId
      "email": "user@example.com",
      "displayName": "testuser",
      "passwordHash": "JDJhJDEwJE9CcDJoeEI3VGFZWmdLeVRpWTQ4bHVhd2xUdVlBVTZCcXp4SmZwSG9KTWRabWphRjRIRmg2",
    },
    {
      "localId": "fghij5678",  // Parse objectId
      "displayName": "wXyZ987654321StUv",
      "providerUserInfo": [
        {
          "providerId": "facebook.com",
          "rawId": "1000000000",  // Facebook ID
        }
      ]
    }
  ]
}

أخيرًا ، قم باستيراد الملف المحول باستخدام Firebase CLI ، مع تحديد bcrypt كخوارزمية التجزئة:

firebase auth:import account_file.json --hash-algo=BCRYPT

ترحيل بيانات المستخدم

إذا كنت تخزن بيانات إضافية للمستخدمين ، فيمكنك ترحيلها إلى Firebase Realtime Database باستخدام الاستراتيجيات الموضحة في قسم ترحيل البيانات . إذا قمت بترحيل الحسابات باستخدام التدفق الموضح في قسم ترحيل الحسابات ، فإن حسابات Firebase لها نفس المعرّفات لحسابات Parse ، مما يسمح لك بترحيل واستنساخ أي علاقات بمفتاح معرف المستخدم بسهولة.

Firebase Cloud Messaging

Firebase Cloud Messaging (FCM) هو حل مراسلة عبر الأنظمة الأساسية يتيح لك تسليم الرسائل والإشعارات بشكل موثوق بدون تكلفة. مؤلف الإخطارات هي خدمة مجانية مبنية على Firebase Cloud Messaging والتي تمكّن إشعارات المستخدم المستهدفة لمطوري تطبيقات الجوال.

اطلع على مستندات Firebase Cloud Messaging لمعرفة المزيد.

الاختلافات مع دفع إخطارات التحليل

يحتوي كل تطبيق Parse مثبت على جهاز مسجل للإعلامات على كائن Installation مرتبط ، حيث تقوم بتخزين جميع البيانات المطلوبة لاستهداف الإشعارات. Installation هو فئة فرعية من ParseUser ، مما يعني أنه يمكنك إضافة أي بيانات إضافية تريدها إلى مثيلات Installation الخاصة بك.

يوفر مؤلف الإشعارات شرائح مستخدم محددة مسبقًا استنادًا إلى معلومات مثل التطبيق وإصدار التطبيق ولغة الجهاز. يمكنك إنشاء شرائح مستخدم أكثر تعقيدًا باستخدام أحداث Google Analytics وخصائصه لبناء جماهير. راجع دليل مساعدة الجمهور لمعرفة المزيد. معلومات الاستهداف هذه غير مرئية في قاعدة بيانات Firebase Realtime.

استراتيجية الهجرة المقترحة

ترحيل رموز الجهاز

في وقت كتابة هذا التقرير ، يستخدم Parse Android SDK إصدارًا قديمًا من رموز تسجيل FCM ، وهو غير متوافق مع الميزات التي يقدمها مؤلف الإشعارات.

يمكنك الحصول على رمز مميز جديد عن طريق إضافة FCM SDK إلى تطبيقك ؛ ومع ذلك ، قد يؤدي هذا إلى إبطال الرمز المميز الذي تستخدمه Parse SDK لتلقي الإعلامات. إذا كنت ترغب في تجنب ذلك ، يمكنك إعداد Parse SDK لاستخدام كل من معرف مرسل Parse ومعرف المرسل الخاص بك. بهذه الطريقة لا تقوم بإبطال الرمز المميز الذي تستخدمه Parse SDK ، ولكن يجب أن تدرك أن هذا الحل البديل سيتوقف عن العمل عندما يقوم Parse بإغلاق مشروعه.

ترحيل القنوات إلى موضوعات FCM

إذا كنت تستخدم قنوات التوزيع لإرسال الإشعارات ، فيمكنك الترحيل إلى موضوعات FCM ، التي توفر نفس نموذج الناشر-المشترك. للتعامل مع الانتقال من Parse إلى FCM ، يمكنك كتابة إصدار جديد من التطبيق يستخدم Parse SDK لإلغاء الاشتراك من قنوات Parse و FCM SDK للاشتراك في موضوعات FCM المقابلة. في هذا الإصدار من التطبيق ، يجب عليك تعطيل تلقي الإشعارات على Parse SDK ، وإزالة ما يلي من بيان تطبيقك:

 <service android:name="com.parse.PushService" />
<receiver android:name="com.parse.ParsePushBroadcastReceiver"
  android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<receiver android:name="com.parse.GcmBroadcastReceiver"
  android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />

<!--
IMPORTANT: Change "com.parse.starter" to match your app's package name.
-->
<category android:name="com.parse.starter" />
</intent-filter>
</receiver>

<!--
IMPORTANT: Change "YOUR_SENDER_ID" to your GCM Sender Id.
-->
<meta-data android:name="com.parse.push.gcm_sender_id"
  android:value="id:YOUR_SENDER_ID" />;
 

على سبيل المثال ، إذا كان المستخدم مشتركًا في موضوع "Giants" ، فستفعل شيئًا مثل:

 ParsePush.unsubscribeInBackground("Giants", new SaveCallback() {
    @Override
    public void done(ParseException e) {
        if (e == null) {
            FirebaseMessaging.getInstance().subscribeToTopic("Giants");
        } else {
            // Something went wrong unsubscribing
        }
    }
});
 

باستخدام هذه الاستراتيجية ، يمكنك إرسال رسائل إلى كل من قناة Parse وموضوع FCM المقابل ، لدعم مستخدمي كل من الإصدارات القديمة والجديدة. عندما يقوم عدد كافٍ من المستخدمين بالترحيل من إصدار Parse-only من التطبيق ، يمكنك إنهاء ذلك الإصدار والبدء في الإرسال باستخدام FCM فقط.

راجع مستندات موضوعات FCM لمعرفة المزيد.

Firebase Remote Config

Firebase Remote Config عبارة عن خدمة سحابية تتيح لك تغيير سلوك ومظهر تطبيقك دون مطالبة المستخدمين بتنزيل تحديث التطبيق. عند استخدام Remote Config ، تقوم بإنشاء قيم افتراضية داخل التطبيق تتحكم في سلوك تطبيقك ومظهره. بعد ذلك ، يمكنك استخدام وحدة تحكم Firebase لاحقًا لتجاوز القيم الافتراضية داخل التطبيق لجميع مستخدمي التطبيق أو لشرائح قاعدة المستخدم الخاصة بك.

يمكن أن يكون Firebase Remote Config مفيدًا جدًا أثناء عمليات الترحيل في الحالات التي تريد فيها اختبار حلول مختلفة والقدرة على تحويل المزيد من العملاء ديناميكيًا إلى مزود آخر. على سبيل المثال ، إذا كان لديك إصدار من تطبيقك يستخدم كلاً من Firebase و Parse للبيانات ، فيمكنك استخدام قاعدة النسبة المئوية العشوائية لتحديد العملاء الذين قرأوا من Firebase ، وزيادة النسبة المئوية تدريجيًا.

لمعرفة المزيد حول Firebase Remote Config ، راجع مقدمة Remote Config .

الاختلافات مع تكوين التحليل

باستخدام Parse config ، يمكنك إضافة أزواج المفتاح / القيمة إلى تطبيقك على لوحة تحكم ParseConfig Config ، ثم إحضار ParseConfig على العميل. كل مثيل ParseConfig الذي تحصل عليه غير قابل للتغيير دائمًا. عندما تقوم باسترداد ParseConfig جديد في المستقبل من الشبكة ، لن يقوم بتعديل أي مثيل ParseConfig موجود ، بل سيقوم بدلاً من ذلك بإنشاء مثيل جديد وإتاحته عبر getCurrentConfig() .

باستخدام Firebase Remote Config ، يمكنك إنشاء إعدادات افتراضية داخل التطبيق لأزواج المفاتيح / القيم التي يمكنك تجاوزها من وحدة تحكم Firebase ، ويمكنك استخدام القواعد والشروط لتقديم اختلافات في تجربة مستخدم تطبيقك إلى شرائح مختلفة من قاعدة المستخدم. يطبّق Firebase Remote Config فئة على فئة أحادية تجعل أزواج المفتاح / القيمة متاحة لتطبيقك. مبدئيًا ، يقوم المفرد بإرجاع القيم الافتراضية التي تحددها داخل التطبيق. يمكنك جلب مجموعة جديدة من القيم من الخادم في أي لحظة ملائمة لتطبيقك ؛ بعد جلب المجموعة الجديدة بنجاح ، يمكنك اختيار وقت تنشيطها لإتاحة القيم الجديدة للتطبيق.

استراتيجية الهجرة المقترحة

يمكنك الانتقال إلى Firebase Remote Config عن طريق نسخ أزواج المفتاح / القيمة الخاصة بتكوين Parse إلى وحدة تحكم Firebase ، ثم نشر إصدار جديد من التطبيق الذي يستخدم Firebase Remote Config.

إذا كنت ترغب في تجربة كل من Parse Config و Firebase Remote Config ، فيمكنك نشر إصدار جديد من التطبيق يستخدم كلاً من SDK حتى يتم ترحيل عدد كافٍ من المستخدمين من إصدار Parse فقط.

مقارنة الكود

تحليل

 ParseConfig.getInBackground(new ConfigCallback() {
    @Override
    public void done(ParseConfig config, ParseException e) {
        if (e == null) {
            Log.d("TAG", "Yay! Config was fetched from the server.");
        } else {
            Log.e("TAG", "Failed to fetch. Using Cached Config.");
            config = ParseConfig.getCurrentConfig();
        }

        // Get the message from config or fallback to default value
        String welcomeMessage = config.getString("welcomeMessage", "Welcome!");
    }
});
 

Firebase

 mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
// Set defaults from an XML resource file stored in res/xml
mFirebaseRemoteConfig.setDefaults(R.xml.remote_config_defaults);

mFirebaseRemoteConfig.fetch()
    .addOnSuccessListener(new OnSuccessListener<Void>() {
        @Override
        public void onSuccess(Void aVoid) {
            Log.d("TAG", "Yay! Config was fetched from the server.");
            // Once the config is successfully fetched it must be activated before newly fetched
            // values are returned.
            mFirebaseRemoteConfig.activateFetched();
        }
    })
    .addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            Log.e("TAG", "Failed to fetch. Using last fetched or default.");
        }
    })

// ...

// When this is called, the value of the latest fetched and activated config is returned;
// if there's none, the default value is returned.
String welcomeMessage = mFirebaseRemoteConfig.getString("welcomeMessage");