Przenoszenie aplikacji Parse na Androida do Firebase

Jeśli jesteś użytkownikiem Parse i poszukujesz alternatywnego rozwiązania typu Backend as a Service, Firebase może być idealnym wyborem dla Twojej aplikacji na Androida.

Z tego przewodnika dowiesz się, jak zintegrować określone usługi z aplikacją. Podstawowe instrukcje konfigurowania Firebase znajdziesz w przewodniku Konfiguracja na Androidzie.

Google Analytics

Google Analytics to bezpłatne rozwiązanie do pomiaru skuteczności aplikacji, które dostarcza informacji o jej użytkowaniu i zaangażowaniu użytkowników. Analytics integruje się z funkcjami Firebase i zapewnia nieograniczone raportowanie nawet 500 różnych zdarzeń, które możesz definiować za pomocą pakietu SDK Firebase.

Aby dowiedzieć się więcej, zapoznaj się z dokumentacją Google Analytics.

Sugerowana strategia migracji

Korzystanie z różnych usług analitycznych to typowy scenariusz, który łatwo zastosować w przypadku Google Analytics. Wystarczy, że dodasz go do aplikacji, aby korzystać z danych o zdarzeniach i właściwościach użytkowników, które Analyticszbiera automatycznie, np. o pierwszym otwarciu, aktualizacji aplikacji, modelu urządzenia czy jego wieku.

W przypadku zdarzeń niestandardowych i właściwości użytkownika możesz zastosować strategię podwójnego zapisu, używając zarówno Parse Analytics, jak i Google Analytics do rejestrowania zdarzeń i właściwości. Dzięki temu możesz stopniowo wdrażać nowe rozwiązanie.

Porównanie kodu

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 to chmurowa baza danych NoSQL. Dane są przechowywane w formacie JSON i synchronizowane w czasie rzeczywistym ze wszystkimi połączonymi klientami.

Aby dowiedzieć się więcej, zapoznaj się z dokumentacją Firebase Realtime Database.

Różnice w przypadku danych z parse

Obiekty

W usłudze Parse przechowujesz obiekt ParseObject lub jego podklasę, który zawiera pary klucz-wartość danych zgodnych z formatem JSON. Dane są bezschematowe, co oznacza, że nie musisz określać, jakie klucze występują w każdym elemencie ParseObject.

Wszystkie dane Firebase Realtime Database są przechowywane jako obiekty JSON, a ParseObject nie ma odpowiednika. Wystarczy, że zapiszesz wartości typu JSON w drzewie, które odpowiadają dostępnym typom JSON. Aby uprościć odczytywanie i zapisywanie danych z bazy danych, możesz używać obiektów Java.

Poniżej znajdziesz przykład zapisywania rekordów w grze.

Analizuj
@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);
Więcej informacji znajdziesz w przewodniku Czytanie i zapisywanie danych na urządzeniach z Androidem.

Relacje między danymi

ParseObject może mieć relację z innym ParseObject: każdy obiekt może używać innych obiektów jako wartości.

Firebase Realtime Database relacje są lepiej wyrażane za pomocą płaskich struktur danych, które dzielą dane na osobne ścieżki, aby można je było efektywnie pobierać w osobnych wywołaniach.

Poniżej przedstawiamy przykład struktury relacji między postami w aplikacji do blogowania a ich autorami.

Analizuj
// 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);

Wynikiem jest poniższy układ danych.

{
  // 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"
    }
    ...
  }
}
Więcej informacji znajdziesz w przewodniku Uporządkuj bazę danych.

Czytanie danych

W usłudze Parse możesz odczytywać dane, używając identyfikatora konkretnego obiektu Parse lub wykonując zapytania za pomocą ParseQuery.

W Firebase dane pobierasz, dołączając asynchronicznego odbiornika do odwołania do bazy danych. Listener jest uruchamiany raz w przypadku początkowego stanu danych i ponownie, gdy dane ulegną zmianie, więc nie musisz dodawać żadnego kodu, aby określić, czy dane się zmieniły.

Poniżej znajdziesz przykładowy sposób pobierania wyników konkretnego gracza na podstawie przykładu przedstawionego w sekcji „Obiekty”.

Analizuj
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());
    }
});
Więcej informacji o dostępnych typach odbiorników zdarzeń oraz o porządkowaniu i filtrowaniu danych znajdziesz w poradniku Czytanie i zapisywanie danych na Androidzie.

Sugerowana strategia migracji

Pomyśl, co jesz

Firebase Realtime Database jest zoptymalizowany pod kątem synchronizacji danych w milisekundach na wszystkich połączonych klientach, a wynikająca z tego struktura danych różni się od danych podstawowych usługi Parse. Oznacza to, że pierwszym krokiem w migracji jest rozważenie, jakich zmian wymagają Twoje dane, w tym:

  • Jak mapować obiekty Parse na dane Firebase
  • Jeśli masz relacje nadrzędne i podrzędne, jak podzielić dane na różne ścieżki, aby można je było efektywnie pobierać w osobnych wywołaniach.

Migracja danych

Po podjęciu decyzji o strukturze danych w Firebase musisz zaplanować, jak postąpić w okresie, w którym aplikacja musi zapisywać dane w obu bazach danych. Opcje do wyboru:

Synchronizacja w tle

W tym scenariuszu masz 2 wersje aplikacji: starą, która korzysta z Parse, oraz nową, która korzysta z Firebase. Synchronizacja między tymi bazami danych jest obsługiwana przez kod Parse Cloud (z Parse do Firebase), a Twój kod wykrywa zmiany w Firebase i synchronizuje je z Parse. Zanim zaczniesz korzystać z nowej wersji, musisz:

  • Przekształć istniejące dane Parse na nową strukturę Firebase i zapisz je w pliku Firebase Realtime Database.
  • Napisać funkcje kodu Parse Cloud, które korzystają z interfejsu Firebase REST API, aby zapisywać w nich Firebase Realtime Database zmiany wprowadzone w danych Parse przez starszych klientów.
  • Napisać i wdrożyć kod, który będzie nasłuchiwać zmian w Firebase i synchronizować je z bazą danych Parse.

Taki scenariusz zapewnia wyraźne oddzielenie starego i nowego kodu oraz upraszcza obsługę klientów. Wyzwania związane z tym scenariuszem to obsługa dużych zbiorów danych podczas początkowego eksportu oraz zapewnienie, że synchronizacja dwukierunkowa nie spowoduje nieskończonej rekurencji.

Podwójny zapis

W tym scenariuszu piszesz nową wersję aplikacji, która korzysta zarówno z Firebase, jak i z Parse. Używasz kodu Parse Cloud do synchronizowania zmian wprowadzonych przez starych klientów z danych Parse na serwer Firebase Realtime Database. Gdy wystarczająca liczba osób przejdzie z wersji aplikacji korzystającej tylko z Parse, możesz usunąć kod Parse z wersji z podwójnym zapisem.

W tym scenariuszu nie trzeba używać kodu po stronie serwera. Wadą tego rozwiązania jest to, że dane, do których nie ma dostępu, nie są migrowane, a rozmiar aplikacji zwiększa się z powodu używania obu pakietów SDK.

Firebase Authentication

Firebase Authentication może uwierzytelniać użytkowników za pomocą haseł i popularnych dostawców tożsamości sfederowanej, takich jak Google, Facebook i Twitter. Udostępnia też biblioteki interfejsu użytkownika, aby zaoszczędzić Ci znaczne nakłady finansowe wymagane do wdrożenia i utrzymania pełnego procesu uwierzytelniania w aplikacji na wszystkich platformach.

Aby dowiedzieć się więcej, zapoznaj się z dokumentacją Firebase Authentication.

Różnice w przypadku funkcji Parse Auth

Parse udostępnia wyspecjalizowaną klasę użytkowników o nazwie ParseUser, która automatycznie obsługuje funkcje wymagane do zarządzania kontami użytkowników. ParseUser jest podklasą ParseObject, co oznacza, że dane użytkownika są dostępne w danych do analizy i można je rozszerzyć o dodatkowe pola, tak jak w przypadku dowolnego innego ParseObject.

Użytkownik FirebaseUser ma stały zestaw podstawowych właściwości: unikalny identyfikator, podstawowy adres e-mail, imię i nazwisko oraz adres URL zdjęcia. Informacje te są przechowywane w oddzielnej bazie danych użytkowników danego projektu. Użytkownik może je aktualizować. Nie możesz bezpośrednio dodawać innych właściwości do obiektu FirebaseUser. Zamiast tego możesz przechowywać dodatkowe właściwości w obiekcie Firebase Realtime Database.

Poniżej przedstawiamy przykład rejestracji użytkownika i dodawania dodatkowego pola numeru telefonu.

Analizuj
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());
            }
        }
    });

Sugerowana strategia migracji

Migracja kont

Aby przenieść konta użytkowników z Parse do Firebase, wyeksportuj bazę danych użytkowników do pliku JSON lub CSV, a potem zaimportuj ten plik do projektu Firebase za pomocą polecenia auth:import w konsoli wiersza poleceń Firebase.

Najpierw wyeksportuj bazę danych użytkowników z konsoli Parse lub z bazy hostowanej lokalnie. Plik JSON wyeksportowany z konsoli Parse może wyglądać tak:

{ // 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",
  ...
}

Następnie przekształcaj wyeksportowany plik w taki format, którego wymaga interfejs wiersza poleceń Firebase. Użyj objectId użytkowników Parse jako localId użytkowników Firebase. Zakoduj też w formacie Base64 wartości bcryptPassword z Parse i użyj ich w polu passwordHash. Przykład:

{
  "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
        }
      ]
    }
  ]
}

Na koniec zaimportuj przekształcony plik za pomocą interfejsu wiersza poleceń Firebase, określając bcrypt jako algorytm haszowania:

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

Migracja danych użytkownika

Jeśli przechowujesz dodatkowe dane użytkowników, możesz je przenieść do Firebase Realtime Database, korzystając ze strategii opisanych w sekcji Migracja danych. Jeśli zrealizujesz migrację kont za pomocą procesu opisanego w sekcji migracja kont, Twoje konta Firebase będą miały te same identyfikatory co konta Parse, co pozwoli Ci łatwo migrować i odtwarzać relacje powiązane z identyfikatorem użytkownika.

Firebase Cloud Messaging

Firebase Cloud Messaging (FCM) to wieloplatformowe rozwiązanie do przesyłania wiadomości, które umożliwia niezawodne przesyłanie wiadomości i powiadomień bez opłat. Narzędzie do tworzenia powiadomień to bezpłatna usługa oparta na Firebase Cloud Messaging, która umożliwia deweloperom aplikacji mobilnych wysyłanie ukierunkowanych powiadomień do użytkowników.

Aby dowiedzieć się więcej, zapoznaj się z dokumentacją Firebase Cloud Messaging .

Różnice w powiadomieniach push w usłudze Parse

Każda aplikacja Parse zainstalowana na urządzeniu zarejestrowanym na potrzeby powiadomień ma powiązany obiekt Installation, w którym przechowujesz wszystkie dane potrzebne do kierowania powiadomień. Installation jest podklasą ParseUser, co oznacza, że możesz dodać dowolne dodatkowe dane do instancji Installation.

Edytor powiadomień udostępnia wstępnie zdefiniowane segmenty użytkowników na podstawie takich informacji jak aplikacja, wersja aplikacji i język urządzenia. Korzystając z tych zdarzeń i właściwości, możesz tworzyć bardziej złożone segmenty użytkowników, aby tworzyć listy odbiorców.Google Analytics Więcej informacji znajdziesz w przewodniku pomocy dotyczącym odbiorców. Te informacje kierunkowe nie są widoczne w Firebase Realtime Database.

Sugerowana strategia migracji

Migracja tokenów urządzeń

W momencie pisania tego tekstu pakiet SDK Parse na Androida używa starszej wersji tokenów rejestracji FCM, która nie jest zgodna z funkcjami oferowanymi przez edytor powiadomień.

Możesz uzyskać nowy token, dodając do aplikacji pakiet FCM SDK. Może to jednak spowodować unieważnienie tokenu używanego przez pakiet SDK Parse do odbierania powiadomień. Jeśli chcesz tego uniknąć, możesz skonfigurować pakiet SDK Parse tak, aby używał zarówno identyfikatora nadawcy Parse, jak i Twojego identyfikatora nadawcy. W ten sposób nie unieważniasz tokena używanego przez pakiet SDK Parse. Pamiętaj jednak, że to obejście przestanie działać, gdy Parse zamknie swój projekt.

Migracja kanałów do FCM Topics

Jeśli do wysyłania powiadomień używasz kanałów Parse, możesz przejść na tematy FCM, które zapewniają ten sam model wydawca–subskrybent. Aby przejść z Parse na FCM, możesz napisać nową wersję aplikacji, która używa pakietu Parse SDK do anulowania subskrypcji kanałów Parse i pakietu FCM SDK do subskrybowania odpowiednich tematów FCM. W tej wersji aplikacji musisz wyłączyć otrzymywanie powiadomień w pakiecie SDK usługi Parse, usuwając z pliku manifestu aplikacji te elementy:

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

Jeśli na przykład użytkownik subskrybuje temat „Giants”, możesz wykonać te czynności:

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

Dzięki tej strategii możesz wysyłać wiadomości zarówno do kanału Parse, jak i do odpowiedniego FCMtematu, obsługując użytkowników zarówno starszej, jak i nowej wersji. Gdy wystarczająca liczba użytkowników przejdzie z wersji aplikacji korzystającej tylko z Parse, możesz wycofać tę wersję i rozpocząć wysyłanie tylko za pomocą FCM.

Aby dowiedzieć się więcej, zapoznaj się z dokumentami dotyczącymi FCM.

Firebase Remote Config

Firebase Remote Config to usługa w chmurze, która pozwala zmienić działanie i wygląd aplikacji bez potrzeby pobierania aktualizacji przez użytkowników. Dzięki Zdalnej konfiguracji tworzysz w aplikacji domyślne wartości, które kontrolują jej zachowanie i wygląd. Później możesz użyć konsoli Firebase, żeby nadpisywać domyślne wartości w aplikacjach wszystkich użytkowników lub ich wybranego segmentu.

Firebase Remote Config może być bardzo przydatna podczas migracji, gdy chcesz przetestować różne rozwiązania i dynamicznie przenosić większą liczbę klientów do innego dostawcy. Jeśli na przykład masz wersję aplikacji, która do przechowywania danych używa zarówno Firebase, jak i Parse, możesz użyć reguły losowego odsetka, aby określić, którzy klienci mają odczytywać dane z Firebase, a potem stopniowo zwiększać ten odsetek.

Więcej informacji o Firebase Remote Config znajdziesz w artykule Wprowadzenie do Remote Config.

Różnice w konfiguracji parsowania

Dzięki konfiguracji Parse możesz dodawać do aplikacji pary klucz-wartość na karcie Konfiguracja Parse, a potem pobierać ParseConfig na kliencie. Każda instancja ParseConfig, którą otrzymasz, jest zawsze niezmienna. Gdy w przyszłości pobierzesz nową wersję ParseConfig z sieci, nie zmieni to żadnej istniejącej instancji ParseConfig, ale utworzy nową i umieści ją w dostępnej sieci getCurrentConfig().

Dzięki Firebase Remote Config możesz tworzyć w aplikacji domyślne wartości par klucz-wartość, które możesz zastąpić w konsoli Firebase. Możesz też używać reguł i warunków, aby modyfikować funkcjonalność aplikacji w różnych segmentach jej użytkowników. Firebase Remote Config implementuje klasę singleton, która udostępnia pary klucz-wartość Twojej aplikacji. Początkowo singleton zwraca wartości domyślne zdefiniowane w aplikacji. Możesz pobrać nowy zestaw wartości z serwera w dowolnym dogodnym momencie. Po pomyślnym pobraniu nowego zestawu możesz wybrać, kiedy go aktywować, aby udostępnić nowe wartości aplikacji.

Sugerowana strategia migracji

Aby przejść na Firebase Remote Config, skopiuj pary klucz-wartość z konfiguracji Parse do konsoli Firebase, a potem wdróż nową wersję aplikacji, która korzysta z Firebase Remote Config.

Jeśli chcesz eksperymentować z obiema usługami – Parse Config i Firebase Remote Config – możesz wdrożyć nową wersję aplikacji, która korzysta z obu pakietów SDK, dopóki wystarczająca liczba użytkowników nie przejdzie z wersji tylko z Parse.

Porównanie kodu

Analizuj

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