انتقال برنامه Parse Android به Firebase

اگر کاربر Parse هستید و به‌دنبال راهکار جایگزین «پشتیبان به‌عنوان سرویس» می‌گردید، Firebase می‌تواند انتخاب ایده‌آلی برای برنامه Android شما باشد.

این راهنما نحوه ادغام سرویس‌های خاص در برنامه را توضیح می‌دهد. برای دستورالعمل‌های راه‌اندازی پایه Firebase، به راهنمای راه‌اندازی Android مراجعه کنید.

Google Analytics

Google Analytics راه‌حل سنجش برنامه رایگانی است که اطلاعات آماری درباره استفاده از برنامه و تعامل کاربر ارائه می‌دهد. ‫Analytics در سراسر ویژگی‌های Firebase ادغام می‌شود و گزارش‌دهی نامحدود برای حداکثر ۵۰۰ رویداد متمایز که می‌توانید بااستفاده از «کیت توسعه نرم‌افزار Firebase» تعریف کنید دراختیارتان قرار می‌دهد.

برای اطلاعات بیشتر، اسناد Google Analytics را ببینید.

استراتژی پیشنهادی انتقال

استفاده از ارائه‌دهندگان تجزیه‌وتحلیل مختلف سناریویی رایج است که به‌راحتی برای Google Analytics اعمال می‌شود. کافی است آن را به برنامه‌تان اضافه کنید تا از رویدادها و مشخصه‌های کاربری که Analytics به‌طور خودکار جمع‌آوری می‌کند بهره‌مند شوید، مثل اولین باز کردن، به‌روزرسانی برنامه، مدل دستگاه، سن.

برای رویدادهای سفارشی و مشخصه‌های کاربر، می‌توانید از استراتژی نوشتن دوگانه بااستفاده از Parse Analytics و Google Analytics برای ثبت رویدادها و مشخصه‌ها استفاده کنید، که به شما امکان می‌دهد راهکار جدید را به‌تدریج عرضه کنید.

مقایسه کد

Parse 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 را ببینید.

تفاوت‌ها با تجزیه داده‌ها

اشیا

در Parse، 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"
    }
    ...
  }
}
برای جزئیات بیشتر، راهنمای ساختاردهی پایگاه داده را بررسی کنید.

خواندن داده‌ها

در Parse، داده‌ها را بااستفاده از شناسه یک شیء Parse خاص یا اجرای پُرسمان‌ها بااستفاده از 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 Database برای همگام‌سازی داده‌ها در چند میلی‌ثانیه در همه کلاینت‌های متصل بهینه شده است و ساختار داده‌های حاصل با داده‌های اصلی Parse متفاوت است. این یعنی اولین گام انتقال شما این است که درنظر بگیرید داده‌هایتان به چه تغییراتی نیاز دارد، ازجمله:

  • نحوه نگاشت کردن عناصر Parse به داده‌های Firebase
  • اگر روابط والد-فرزند دارید، چگونه داده‌های خود را در مسیرهای مختلف تقسیم کنید تا بتوان آن را به‌طور کارآمد در تماس‌های جداگانه بارگیری کرد.

انتقال داده‌ها

پس‌از اینکه تصمیم گرفتید داده‌هایتان را در Firebase چگونه ساختاربندی کنید، باید برنامه‌ریزی کنید که چگونه دوره‌ای را که برنامه‌تان باید در هر دو پایگاه داده بنویسد مدیریت کنید. انتخاب‌های شما عبارتند از:

همگام‌سازی پس‌زمینه

در این سناریو، دو نسخه از برنامه دارید: نسخه قدیمی که از Parse استفاده می‌کند و نسخه جدیدی که از Firebase استفاده می‌کند. همگام‌سازی بین دو پایگاه داده توسط Parse Cloud Code (از Parse به Firebase) انجام می‌شود، به‌طوری‌که کد شما تغییرات Firebase را گوش می‌دهد و آن تغییرات را با Parse همگام‌سازی می‌کند. پیش‌از اینکه بتوانید از نسخه جدید استفاده کنید، باید:

  • داده‌های تجزیه‌شده موجود را به ساختار جدید Firebase تبدیل کنید و آن را در Firebase Realtime Database بنویسید.
  • توابع Parse Cloud Code را بنویسید که از Firebase REST API برای نوشتن در Firebase Realtime Database تغییرات ایجادشده در Parse Data توسط کلاینت‌های قدیمی استفاده می‌کنند.
  • کدی بنویسید و آن را مستقر کنید که به تغییرات Firebase گوش می‌دهد و آن‌ها را با پایگاه داده Parse همگام‌سازی می‌کند.

این سناریو جداسازی تمیز کد قدیمی و جدید را تضمین می‌کند و کلاینت‌ها را ساده نگه می‌دارد. چالش‌های این سناریو عبارت‌اند از مدیریت مجموعه داده‌های بزرگ در صادر کردن اولیه و اطمینان از اینکه همگام‌سازی دوطرفه بازگشت بی‌نهایت ایجاد نمی‌کند.

نوشتن مضاعف

در این سناریو، نسخه جدیدی از برنامه می‌نویسید که از Firebase و Parse استفاده می‌کند، و از Parse Cloud Code برای همگام‌سازی تغییرات ایجادشده توسط مشتریان قدیمی از Parse Data به Firebase Realtime Database استفاده می‌کند. وقتی افراد کافی از نسخه فقط Parse برنامه مهاجرت کردند، می‌توانید کد Parse را از نسخه نوشتن دوگانه بردارید.

این سناریو به کد سمت سرور نیاز ندارد. معایب آن این است که داده‌هایی که به آن‌ها دسترسی پیدا نشده است منتقل نمی‌شوند و اندازه برنامه‌تان به‌دلیل استفاده از هر دو کیت توسعه نرم‌افزار افزایش می‌یابد.

Firebase Authentication

‫Firebase Authentication می‌تواند کاربران را بااستفاده از گذرواژه‌ها و ارائه‌دهندگان هویت فدرال محبوب مثل Google،‏ Facebook، و X (توییتر سابق) اصالت‌سنجی کند. همچنین کتابخانه‌های میانای کاربری را ارائه می‌دهد تا از سرمایه‌گذاری قابل‌توجهی که برای پیاده‌سازی و حفظ تجربه اصالت‌سنجی کامل برای برنامه شما در همه پلاتفرم‌ها لازم است جلوگیری کند.

برای اطلاعات بیشتر، اسناد Firebase Authentication را ببینید.

تفاوت‌ها با Parse Auth

‫Parse کلاس کاربر تخصصی‌ای به‌نام ParseUser ارائه می‌دهد که به‌طور خودکار عملکرد موردنیاز برای مدیریت حساب کاربر را انجام می‌دهد. ParseUser زیرکلاسی از ParseObject است، یعنی داده‌های کاربر در Parse Data دردسترس است و می‌توان آن را با فیلدهای اضافی مانند هر ParseObject دیگری گسترش داد.

FirebaseUser مجموعه‌ای ثابت از دارایی‌های پایه دارد—شناسه یکتا، نشانی ایمیل اصلی، نام، و نشانی وب عکس—که در پایگاه داده کاربر پروژه جداگانه‌ای ذخیره می‌شود؛ این دارایی‌ها را کاربر می‌تواند به‌روز کند. نمی‌توانید دارایی‌های دیگر را مستقیماً به شیء 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 صادر کنید، سپس فایل را بااستفاده از فرمان auth:import در واسط خط فرمان Firebase به پروژه Firebase خود وارد کنید.

ابتدا پایگاه داده کاربر خود را از کنسول 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 کاربران Parse خود به‌عنوان localId کاربران Firebase خود استفاده کنید. همچنین، مقادیر bcryptPassword را از Parse با کدبندی base64 کدگذاری کنید و از آن‌ها در فیلد 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

هر برنامه Parse نصب‌شده در دستگاهی که برای اعلان‌ها ثبت شده است، یک شیء Installation مرتبط دارد که در آن همه داده‌های موردنیاز برای هدف‌یابی اعلان‌ها را ذخیره می‌کنید. ‫Installation زیرکلاسی از ParseUser است، یعنی می‌توانید هر داده اضافی‌ای را که می‌خواهید به نمونه‌های Installation خود اضافه کنید.

ترکیب‌کننده «اعلان‌ها» براساس اطلاعاتی مثل برنامه، نسخه برنامه، و زبان دستگاه، بخش‌های کاربر ازپیش تعریف‌شده‌ای را ارائه می‌دهد. می‌توانید بااستفاده از Google Analytics رویدادها و دارایی‌ها بخش‌های کاربر پیچیده‌تری برای ساختن مخاطبان بسازید. برای کسب اطلاعات بیشتر، راهنمای کمک مخاطبان را ببینید. این اطلاعات هدف‌یابی در Firebase Realtime Database قابل‌مشاهده نیست.

استراتژی انتقال پیشنهادی

انتقال دادن کدهای دستگاه

در زمان نوشتن، Parse Android SDK از نسخه قدیمی‌تر نشان‌های ثبت FCM استفاده می‌کند که با ویژگی‌های ارائه‌شده توسط سازنده اعلان‌ها سازگار نیست.

با افزودن FCM SDK به برنامه‌تان می‌توانید یک کد جدید دریافت کنید؛ اما، این کار ممکن است کد استفاده‌شده توسط Parse SDK را برای دریافت اعلان‌ها نامعتبر کند. اگر می‌خواهید از این اتفاق جلوگیری کنید، می‌توانید «کیت توسعه نرم‌افزار Parse» را طوری تنظیم کنید که هم از شناسه فرستنده Parse و هم از شناسه فرستنده خودتان استفاده کند. به‌این ترتیب، نشان مورد استفاده کیت توسعه نرم‌افزار Parse را نامعتبر نمی‌کنید، اما توجه داشته باشید که این راهکار موقت وقتی Parse پروژه‌اش را تعطیل کند دیگر کار نخواهد کرد.

انتقال کانال‌ها به موضوعات FCM

اگر از کانال‌های Parse برای ارسال اعلان‌ها استفاده می‌کنید، می‌توانید به موضوعات 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 برنامه منتقل شدند، می‌توانید آن نسخه را از رده خارج کنید و ارسال را فقط بااستفاده از FCM شروع کنید.

برای اطلاعات بیشتر، اسناد موضوعات FCM را ببینید.

Firebase Remote Config

Firebase Remote Config سرویسی ابری است که به شما امکان می‌دهد رفتار و ظاهر برنامه‌تان را بدون نیاز به بارگیری به‌روزرسانی برنامه توسط کاربران تغییر دهید. هنگام استفاده از «پیکربندی از دور»، مقادیر پیش‌فرض درون‌برنامه‌ای ایجاد می‌کنید که رفتار و ظاهر برنامه شما را کنترل می‌کنند. سپس می‌توانید از کنسول Firebase برای ملغی کردن مقادیر پیش‌فرض درون‌برنامه‌ای برای همه کاربران برنامه یا برای بخش‌هایی از پایگاه کاربرانتان استفاده کنید.

Firebase Remote Config می‌تواند درطول انتقال‌های شما بسیار مفید باشد، در مواردی که می‌خواهید راه‌حل‌های مختلف را آزمایش کنید و بتوانید به‌طور پویا مشتریان بیشتری را به ارائه‌دهنده دیگری منتقل کنید. برای مثال، اگر نسخه‌ای از برنامه خود دارید که هم از Firebase و هم از Parse برای داده‌ها استفاده می‌کند، می‌توانید از قانون درصد تصادفی برای تعیین اینکه کدام مشتریان از Firebase بخوانند استفاده کنید و به‌تدریج درصد را افزایش دهید.

برای کسب اطلاعات بیشتر درباره Firebase Remote Config، Remote Configمقدمه را ببینید.

تفاوت‌ها با پیکربندی تجزیه

با Parse config می‌توانید جفت‌های کلید/مقدار را در Parse Config Dashboard به برنامه‌تان اضافه کنید و سپس ParseConfig را در کارخواه واکشی کنید. هر نمونه ParseConfig که دریافت می‌کنید همیشه تغییرناپذیر است. وقتی در آینده ParseConfig جدیدی را از شبکه بازیابی می‌کنید، هیچ نمونه ParseConfig موجودی را تغییر نخواهد داد، بلکه نمونه جدیدی ایجاد خواهد کرد و آن را ازطریق getCurrentConfig() دردسترس قرار خواهد داد.

با Firebase Remote Config، پیش‌فرض‌های درون‌برنامه‌ای برای جفت‌های کلید/مقدار ایجاد می‌کنید که می‌توانید آن‌ها را از کنسول Firebase ملغی کنید، و می‌توانید از قوانین و شرایط برای ارائه تنوع در تجربه کاربری برنامه‌تان به بخش‌های مختلف پایگاه کاربرانتان استفاده کنید. Firebase Remote Config یک کلاس تک‌قلو را پیاده‌سازی می‌کند که جفت‌های کلید/مقدار را برای برنامه‌تان دردسترس قرار می‌دهد. در ابتدا، کلاس تک‌قلو مقادیر پیش‌فرضی را که در برنامه تعریف می‌کنید برمی‌گرداند. می‌توانید در هر زمانی که برای برنامه‌تان مناسب است، مجموعه جدیدی از مقادیر را از سرور واکشی کنید؛ پس‌از اینکه مجموعه جدید با موفقیت واکشی شد، می‌توانید انتخاب کنید که چه زمانی آن را فعال کنید تا مقادیر جدید برای برنامه دردسترس قرار گیرد.

استراتژی انتقال پیشنهادی

می‌توانید با کپی کردن جفت‌های کلید/مقدار پیکربندی Parse خود در کنسول Firebase و سپس استقرار نسخه جدیدی از برنامه که از Firebase Remote Config استفاده می‌کند، به Firebase Remote Config بروید.

اگر می‌خواهید هم با Parse Config و هم با Firebase Remote Config آزمایش کنید، می‌توانید نسخه جدیدی از برنامه را که از هر دو کیت توسعه نرم‌افزار استفاده می‌کند مستقر کنید تا زمانی که کاربران کافی از نسخه Parse-only مهاجرت کنند.

مقایسه کد

تجزیه کردن

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