העברת אפליקציית Parse ל-Android ל-Firebase

אם אתם משתמשים ב-Parse ומחפשים פתרון חלופי לקצה העורפי בתור שירות, Firebase יכול להיות הפתרון האידיאלי לאפליקציה שלכם ל-Android.

במדריך הזה נסביר איך לשלב שירותים ספציפיים באפליקציה. עבור הוראות בסיסיות להגדרה של Firebase. מידע נוסף זמין במאמר הגדרת Android מותאמת אישית.

Google Analytics

Google Analytics הוא פתרון חינמי למדידת אפליקציות שמספק תובנות לגבי השימוש באפליקציות בהתעניינות המשתמשים. Analytics משתלב בכל התכונות של Firebase ומספק לך גישה ללא הגבלה דיווח לגבי עד 500 אירועים שונים שאפשר להגדיר באמצעות ה-SDK של Firebase.

מידע נוסף זמין במסמכים בנושא Google Analytics.

הצעה לאסטרטגיית העברה

שימוש בספקים שונים של ניתוח נתונים הוא תרחיש נפוץ שניתן ליישם בקלות Google Analytics פשוט מוסיפים אותו לאפליקציה כדי ליהנות מאירועים וממאפייני משתמשים ש-Analytics אוסף באופן אוטומטי, כמו הפתיחה הראשונה, עדכון האפליקציה, דגם המכשיר והגיל.

באירועים מותאמים אישית ובמאפייני משתמש, אפשר להשתמש באסטרטגיית כתיבה כפולה באמצעות לנתח את 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);

Google Analytics

// 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 Realtime Database

Firebase Realtime Database הוא מסד נתונים NoSQL שמתארח בענן. הנתונים מאוחסנים בפורמט JSON מסונכרן בזמן אמת לכל לקוח מחובר.

מידע נוסף זמין במסמכים בנושא Firebase Realtime Database.

הבדלים בנתונים מניתוח הנתונים

Objects

בקטע 'ניתוח' אתם מאחסנים 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 Database, קשרים מתבטאים טוב יותר באמצעות מבני נתונים שטוחים לפצל את הנתונים לנתיבים נפרדים, כדי שניתן יהיה להוריד אותם ביעילות בשיחות נפרדות.

בדוגמה הבאה מוסבר איך אפשר לבנות את הקשר בין פוסטים באפליקציית בלוגים לבין המחברים שלהם.

ניתוח
// 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"
    }
    ...
  }
}
פרטים נוספים זמינים במדריך מבנה מסד הנתונים.

נתוני קריאה

בקטע 'ניתוח' קוראים נתונים באמצעות המזהה של אובייקט ניתוח ספציפי, או ביצוע שאילתות באמצעות ParseQuery.

ב-Firebase, אפשר לאחזר נתונים על ידי צירוף אוזן אסינכרוני להפניה של מסד נתונים. הבורר מופעל פעם אחת עבור המצב הראשוני של הנתונים ופעם נוספת כשהנתונים משתנים, כך שלא תצטרכו להוסיף קוד כדי לקבוע אם הנתונים השתנו.

הדוגמה הבאה ממחישה איך אפשר לאחזר את התוצאות של שחקן מסוים, בהתבסס על הדוגמה שמוצגת בקטע "Objects".

ניתוח
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());
    }
});
פרטים נוספים על הסוגים הזמינים של פונקציות event listener ואיך לסדר ולסנן נתונים, קריאה וכתיבה של נתונים ב-Android מותאמת אישית.

הצעה לאסטרטגיית העברה

חשיבה מחדש על הנתונים

ה-Firebase Realtime Database עבר אופטימיזציה לסנכרון נתונים באלפיות השנייה בכל המכשירים המחוברים לקוחות שונים, ומבנה הנתונים שמתקבל שונה מנתוני הליבה של ניתוח. המשמעות היא השלב הראשון בהעברה הוא לחשוב אילו שינויים צריך לבצע בנתונים, כולל:

  • איך צריך למפות את אובייקטי ה-Parse לנתוני Firebase
  • אם יש לכם קשרי הורה-צאצא, איך לפצל את הנתונים בין נתיבים שונים ניתן להוריד אותו ביעילות בשיחות נפרדות.

העברת הנתונים

אחרי שמחליטים איך לבנות את המבנה של הנתונים ב-Firebase, צריך לתכנן איך לטפל בתקופה שבה האפליקציה צריכה לכתוב בשתי מסדי הנתונים. אלו הן האפשרויות:

סנכרון ברקע

בתרחיש הזה, יש לכם שתי גרסאות של האפליקציה: הגרסה הישנה שמשתמשת ב-Parse והגרסה החדשה גרסה שמשתמשת ב-Firebase. סנכרון בין שתי מסדי הנתונים מתבצע על ידי Parse Cloud Code (Parse ל-Firebase), והקוד שלכם מקשיב לשינויים ב-Firebase ומסנכרן את השינויים האלה עם Parse. לפני שמתחילים להשתמש בגרסה החדשה, צריך:

  • להמיר את הנתונים הקיימים של ניתוח הנתונים למבנה Firebase החדש, ולכתוב אותם Firebase Realtime Database
  • לכתוב פונקציות של Parse Cloud Code שמשתמשות ב-API ל-REST של Firebase כדי לכתוב Firebase Realtime Database שינויים שבוצעו בנתוני ניתוח הנתונים על ידי לקוחות ישנים.
  • כתיבה ופריסה של קוד שמזהה שינויים ב-Firebase ומסנכרן אותם עם Parse מסד נתונים.

התרחיש הזה מבטיח הפרדה ברורה בין הקוד הישן לקוד החדש, ועוזר לשמור על פשטות של הלקוחות. בתרחיש הזה, הטיפול במערכי נתונים גדולים בייצוא הראשוני, ומבטיח סנכרון דו-כיווני לא יוצר רקורסיה אינסופית.

כתיבה כפולה

בתרחיש הזה, אתם כותבים גרסה חדשה של האפליקציה שמשתמשת גם ב-Firebase וגם ב-Parse, באמצעות לנתח את Cloud Code כדי לסנכרן שינויים שבוצעו על ידי לקוחות ישנים מ-Parse Data Firebase Realtime Database אחרי שעברו מספיק אנשים מגרסת האפליקציה 'ניתוח בלבד', אפשר יכול להסיר את הקוד ניתוח מגרסת הכתיבה הכפולה.

בתרחיש הזה לא נדרש קוד בצד השרת. החסרונות שלה הם שנתונים הגישה לא הועברה, והשימוש בשתי ערכות ה-SDK גדל בהתאם לגודל האפליקציה.

Firebase Authentication

ל-Firebase Authentication יש אפשרות לאמת משתמשים באמצעות סיסמאות וספקי זהויות מאוחדים פופולריים כמו Google, Facebook ו-Twitter. היא גם מספקת ספריות ממשק משתמש כדי לחסוך שנדרשת כדי להטמיע ולתחזק חוויית אימות מלאה באפליקציה שלכם כל הפלטפורמות.

מידע נוסף זמין במסמכים בנושא Firebase Authentication.

ההבדלים עם Analytics Auth

הניתוח מספק מחלקה מיוחדת של משתמשים בשם ParseUser שמטפלת באופן אוטומטי הפונקציונליות הנדרשת לניהול חשבון משתמש. ParseUser היא מחלקה משנית של 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 ב-CLI של Firebase הפקודה.

קודם כול, מייצאים את מסד הנתונים של המשתמשים ממסוף Analytics או מאירוח עצמי מסד נתונים. לדוגמה, קובץ JSON שיוצא ממסוף ניתוח עשוי להיראות כמו:

{ // 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 של משתמשי Parse בתור localId של משתמשי Firebase. בנוסף, base64 מקודד את bcryptPassword ערכים מ-Anse ולהשתמש בהם בפונקציה 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
        }
      ]
    }
  ]
}

בשלב האחרון, מייבאים את הקובץ שהומר באמצעות ה-CLI של Firebase, ומציינים 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 מסמכים .

ההבדלים בהתראות 'ניתוח'

לכל אפליקציית ניתוח שמותקנת במכשיר שרשום לקבלת התראות יש אובייקט Installation, שבו מאוחסנים כל הנתונים שצריך כדי לטרגט התראות. Installation הוא תת-מחלקה של ParseUser, כלומר אפשר להוסיף כל נתון נוסף שרוצים למכונות של Installation.

הכלי ליצירת התראות מספק פלחים מוגדרים מראש של משתמשים על סמך מידע כמו האפליקציה, גרסת האפליקציה והשפה של המכשיר. אפשר ליצור פלחי משתמשים מורכבים יותר באמצעות אירועים ונכסים של Google Analytics כדי ליצור קהלים. הצגת הקהלים במדריך האישי שלנו. פרטי הטירגוט האלה לא מוצגים בFirebase Realtime Database.

הצעה לאסטרטגיית העברה

העברת אסימוני המכשיר

נכון למועד הכתיבה, ניתוח ה-SDK של Android משתמש בגרסה ישנה יותר של FCM אסימוני רישום, שלא תואמים לתכונות שמציע 'מלחין ההתראות'.

כדי לקבל אסימון חדש, צריך להוסיף את FCM SDK לאפליקציה. עם זאת, פעולה זו עלולה לבטל את התוקף של האסימון שמשמש את ניתוח ה-SDK לקבלת התראות. אם ברצונך למנוע זאת, אפשר להגדיר ב-Parse SDK להשתמש במזהה השולח של ניתוח הנתונים ומזהה השולח שלכם. כך לא תבטלו את התוקף של האסימון שמשמש את Parse SDK, אבל חשוב לזכור שהפתרון הזה יפסיק לפעול כשהפרויקט ב-Parse יושבת.

העברת ערוצים ל-FCM נושאים

אם אתם משתמשים בערוצי Parse כדי לשלוח התראות, תוכלו לעבור לנושאי FCM, שמספקים את אותו מודל של בעל תוכן דיגיטלי ומנויים. כדי לטפל במעבר מ-Parse ל-FCM, אתם יכולים לכתוב גרסה חדשה. של האפליקציה שמשתמשת ב-Parse SDK כדי לבטל את ההרשמה לערוצים של ניתוח הנתונים וב-FCM SDK כדי להירשם אליהם נושאי ה-FCM המתאימים. צריך להשבית את קבלת ההתראות בגרסה הזו של האפליקציה ניתוח ה-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" />;

לדוגמה, אם המשתמש שלכם רשום לקבוצה של 'הג'יאנטים' , תוכלו לעשות משהו כמו:

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 התואם, וכך לתמוך במשתמשים בגרסה הישנה וגם בגרסה החדשה. אחרי שעברו מספיק משתמשים גרסה לניתוח בלבד של האפליקציה. אפשר לסגור את הגרסה הזו ולהתחיל לשלוח נתונים רק באמצעות FCM.

לצפייה FCM מסמכי נושאים למידע נוסף.

Firebase Remote Config

Firebase Remote Config הוא שירות ענן שמאפשר לשנות את ההתנהגות והמראה של בלי לדרוש מהמשתמשים להוריד עדכון לאפליקציה. כשמשתמשים בהגדרת תצורה מרחוק, צריך ליצור באפליקציה ערכי ברירת מחדל שקובעים את ההתנהגות והמראה של האפליקציה. לאחר מכן תוכלו להשתמש במסוף Firebase אפשר לשנות את ערכי ברירת המחדל בתוך האפליקציה לכל המשתמשים באפליקציה או לפלחים של בסיס המשתמשים.

Firebase Remote Config יכולה להיות שימושית מאוד במהלך ההעברות במקרים שבהם רוצים לבדוק פתרונות שונים, ותוכלו להעביר באופן דינמי יותר לקוחות לספק אחר. לדוגמה, אם יש לך גרסה של האפליקציה שמשתמשת גם ב-Firebase וגם ב-Parse לנתונים, אפשר להשתמש כלל אחוזון אקראי כדי לקבוע אילו לקוחות קוראים מ-Firebase, ולהגדיל את האחוז בהדרגה.

מידע נוסף על Firebase Remote Config זמין ב הקדמה אחת (Remote Config).

ההבדלים בהגדרה 'ניתוח התצורה'

בעזרת Parse config אתם יכולים להוסיף צמדי מפתח/ערך לאפליקציה במרכז הבקרה של Parse Config. מאחזרים את ParseConfig אצל הלקוח. בכל מופע של ParseConfig הוא תמיד לא ניתן לשינוי. כשאחזור ParseConfig חדש מהרשת בעתיד, הוא לא ישנה מכונה קיימת של ParseConfig, אלא ייצור מכונה חדשה ויהפוך אותה לזמינה דרך getCurrentConfig().

עם Firebase Remote Config יוצרים ברירות מחדל בתוך האפליקציה עבור צמדי מפתח/ערך שאפשר לשנות ממסוף Firebase, ולהשתמש בכללים ובתנאים כדי לספק גרסאות בקרב פלחים שונים של בסיס המשתמשים. Firebase Remote Config מטמיע מחלקת סינגלטון שהופכת את צמדי המפתח/ערך לזמינים לאפליקציה. בהתחלה, הסינגלטון חוזר את ערכי ברירת המחדל שאתם מגדירים באפליקציה. אפשר לאחזר קבוצה חדשה של ערכים מהשרת בכל שלב רגעים נוחים לאפליקציה שלך; אחרי שהקבוצה החדשה אוחזרה, אפשר לבחור מתי להפעיל כדי שהערכים החדשים יהיו זמינים לאפליקציה.

הצעה לאסטרטגיית העברה

אפשר לעבור אל Firebase Remote Config על ידי העתקה של צמדי המפתח/ערך של ההגדרה של 'ניתוח' במסוף Firebase, ולאחר מכן לפרוס גרסה חדשה של האפליקציה עם Firebase Remote Config.

אם רוצים להתנסות גם ב-Parse Config וגם ב-Firebase Remote Config, אפשר לפרוס גרסה חדשה של האפליקציה שמשתמשת בשתי ערכות ה-SDK עד שמספיק משתמשים יעברו מהגרסה לניתוח בלבד.

השוואת קוד

ניתוח

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");