Di chuyển ứng dụng Phân tích cú pháp Android sang Firebase

Nếu bạn là một Người dùng Phân tích cú pháp đang tìm kiếm một Phần phụ trợ thay thế làm Firebase có thể là lựa chọn lý tưởng cho ứng dụng Android của bạn.

Hướng dẫn này mô tả cách tích hợp các dịch vụ cụ thể vào ứng dụng của bạn. Cho hướng dẫn thiết lập Firebase cơ bản, hãy xem phần Thiết lập Android của chúng tôi.

Google Analytics

Google Analytics là một giải pháp đo lường ứng dụng miễn phí, cung cấp thông tin chi tiết về mức sử dụng ứng dụng và mức độ tương tác của người dùng. Analytics tích hợp nhiều tính năng của Firebase và cung cấp cho bạn báo cáo cho tối đa 500 sự kiện riêng biệt mà bạn có thể xác định bằng cách sử dụng Firebase SDK.

Hãy xem tài liệu về Google Analytics để tìm hiểu thêm.

Chiến lược di chuyển được đề xuất

Việc sử dụng các nhà cung cấp dịch vụ phân tích khác nhau là một trường hợp phổ biến và dễ dàng áp dụng cho Google Analytics. Chỉ cần thêm đơn vị quảng cáo này vào ứng dụng của bạn để hưởng lợi từ các sự kiện và thuộc tính người dùng mà Analytics tự động thu thập dữ liệu, chẳng hạn như lần mở đầu tiên, bản cập nhật ứng dụng, mẫu thiết bị, độ tuổi.

Đối với sự kiện tuỳ chỉnh và thuộc tính người dùng, bạn có thể triển khai chiến lược ghi kép bằng cách sử dụng cả Phân tích cú pháp Analytics và Google Analytics để ghi lại các sự kiện và tài sản. Nhờ đó, bạn có thể triển khai dần giải pháp mới.

So sánh mã

Phân tích cú pháp số liệu phân tích

// 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 là một cơ sở dữ liệu NoSQL được lưu trữ trên đám mây. Dữ liệu được lưu trữ dưới dạng JSON và được đồng bộ hoá theo thời gian thực với mọi ứng dụng được kết nối.

Hãy xem tài liệu về Firebase Realtime Database để tìm hiểu thêm.

Chênh lệch với dữ liệu phân tích cú pháp

Đối tượng

Trong Trình phân tích cú pháp, bạn lưu trữ một ParseObject hoặc một lớp con trong đó, trong đó có chứa các cặp khoá-giá trị của dữ liệu tương thích với JSON. Dữ liệu không có giản đồ, nghĩa là bạn không cần chỉ định khoá nào tồn tại trên mỗi ParseObject.

Tất cả dữ liệu Firebase Realtime Database đều được lưu trữ dưới dạng đối tượng JSON và không có dữ liệu nào tương đương cho ParseObject; bạn chỉ cần ghi vào giá trị cây JSON của các loại tương ứng với loại JSON có sẵn. Bạn có thể sử dụng các đối tượng Java để đơn giản hoá việc đọc và ghi từ cơ sở dữ liệu.

Sau đây là ví dụ về cách bạn có thể lưu điểm cao của một trò chơi.

Phân tích cú pháp
@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);
Để biết thêm chi tiết, hãy xem Hướng dẫn Đọc và ghi dữ liệu trên Android.

Mối quan hệ giữa dữ liệu

ParseObject có thể có mối quan hệ với một ParseObject khác: bất kỳ đối tượng có thể sử dụng các đối tượng khác làm giá trị.

Trong Firebase Realtime Database, các mối quan hệ được biểu thị tốt hơn bằng cách sử dụng cấu trúc dữ liệu phẳng hãy chia dữ liệu thành các đường dẫn riêng biệt để tải xuống hiệu quả trong các lệnh gọi riêng biệt.

Sau đây là ví dụ về cách bạn có thể xây dựng mối quan hệ giữa các bài đăng trong một ứng dụng viết blog và tác giả của chúng.

Phân tích cú pháp
// 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);

Bố cục dữ liệu sau đây là kết quả.

{
  // 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"
    }
    ...
  }
}
Để biết thêm chi tiết, hãy xem Xây dựng cấu trúc cơ sở dữ liệu của bạn của chúng tôi.

Đọc dữ liệu

Trong Trình phân tích cú pháp, bạn đọc dữ liệu bằng mã nhận dạng của một đối tượng Phân tích cú pháp cụ thể, hoặc thực thi các truy vấn bằng ParseQuery.

Trong Firebase, bạn truy xuất dữ liệu bằng cách đính kèm một trình nghe không đồng bộ vào một tệp tham chiếu cơ sở dữ liệu. Chiến lược phát hành đĩa đơn trình nghe được kích hoạt một lần cho trạng thái ban đầu của dữ liệu và một lần nữa khi dữ liệu thay đổi, vì vậy, bạn sẽ không cần thêm mã nào để xác định xem dữ liệu có thay đổi hay không.

Sau đây là ví dụ về cách bạn có thể truy xuất điểm số cho một người chơi cụ thể, dựa trên ví dụ có trong phần "Đối tượng".

Phân tích cú pháp
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());
    }
});
Để biết thêm thông tin chi tiết về các loại trình nghe sự kiện hiện có cũng như cách sắp xếp và lọc dữ liệu, hãy kiểm tra Đọc và ghi dữ liệu trên Android của chúng tôi.

Chiến lược di chuyển được đề xuất

Cân nhắc lại dữ liệu của bạn

Firebase Realtime Database được tối ưu hoá để đồng bộ hoá dữ liệu tính bằng mili giây trên tất cả thiết bị được kết nối ứng dụng khách và cấu trúc dữ liệu thu được khác với dữ liệu cốt lõi Phân tích cú pháp. Điều này có nghĩa là bước đầu tiên của quá trình di chuyển là xem xét những thay đổi mà dữ liệu của bạn yêu cầu, bao gồm:

  • Cách các đối tượng Phân tích cú pháp sẽ ánh xạ đến dữ liệu Firebase
  • Nếu bạn có quan hệ mẹ con, hãy làm cách nào để phân chia dữ liệu thành nhiều đường dẫn sao cho có thể tải xuống hiệu quả trong các lệnh gọi riêng biệt.

Di chuyển dữ liệu của bạn

Sau khi quyết định cách định cấu trúc dữ liệu trong Firebase, bạn cần lên kế hoạch xử lý khoảng thời gian mà ứng dụng của bạn cần ghi vào cả hai cơ sở dữ liệu. Lựa chọn của bạn là:

Đồng bộ hoá ở chế độ nền

Trong trường hợp này, bạn có hai phiên bản ứng dụng: phiên bản cũ sử dụng tính năng Phân tích cú pháp và một phiên bản mới phiên bản sử dụng Firebase. Quá trình đồng bộ hoá giữa 2 cơ sở dữ liệu được xử lý bằng Phân tích cú pháp mã đám mây (Phân tích cú pháp) với Firebase), với đoạn mã của bạn đang theo dõi các thay đổi trên Firebase và đồng bộ hoá những thay đổi đó bằng Trình phân tích cú pháp. Trước khi có thể bắt đầu sử dụng phiên bản mới, bạn phải:

  • Chuyển đổi dữ liệu phân tích cú pháp hiện tại của bạn sang cấu trúc Firebase mới và ghi dữ liệu đó vào Firebase Realtime Database.
  • Viết các hàm Phân tích cú pháp mã đám mây sử dụng API REST của Firebase để ghi vào Firebase Realtime Database thay đổi do ứng dụng cũ thực hiện trong Phân tích cú pháp dữ liệu.
  • Viết và triển khai mã có khả năng theo dõi các thay đổi trên Firebase và đồng bộ hoá các thay đổi đó với trình phân tích cú pháp cơ sở dữ liệu.

Trường hợp này đảm bảo việc phân tách rõ ràng mã cũ và mã mới, đồng thời giúp đơn giản hoá các ứng dụng. Chiến lược phát hành đĩa đơn thách thức của tình huống này là xử lý các tập dữ liệu lớn trong lần xuất ban đầu và đảm bảo rằng Tính năng đồng bộ hoá hai chiều không tạo ra đệ quy vô hạn.

Ghi kép

Trong trường hợp này, bạn viết một phiên bản ứng dụng mới sử dụng cả Firebase và Phân tích cú pháp, sử dụng Phân tích cú pháp mã đám mây để đồng bộ hoá các thay đổi do các ứng dụng cũ thực hiện từ Phân tích cú pháp dữ liệu sang Firebase Realtime Database. Khi đủ người di chuyển từ phiên bản chỉ Phân tích cú pháp của ứng dụng, bạn có thể xoá mã Phân tích cú pháp khỏi phiên bản ghi kép.

Trường hợp này không yêu cầu mã phía máy chủ. Nhược điểm của phương pháp này là dữ liệu không không bị di chuyển và kích thước ứng dụng của bạn sẽ tăng lên khi bạn sử dụng cả hai SDK.

Firebase Authentication

Firebase Authentication có thể xác thực người dùng bằng mật khẩu và các nhà cung cấp danh tính được liên kết phổ biến chẳng hạn như Google, Facebook và Twitter. API này cũng cung cấp các thư viện giao diện người dùng để giúp bạn tiết kiệm khoản đầu tư cần thiết để triển khai và duy trì trải nghiệm xác thực đầy đủ cho ứng dụng của bạn trên tất cả nền tảng.

Hãy xem tài liệu về Firebase Authentication để tìm hiểu thêm.

Sự khác biệt với tính năng xác thực phân tích cú pháp

Phân tích cú pháp cung cấp một lớp người dùng chuyên biệt có tên là ParseUser. Lớp này tự động xử lý chức năng cần thiết để quản lý tài khoản người dùng. ParseUser là một lớp con của ParseObject, nghĩa là dữ liệu người dùng có trong Dữ liệu phân tích cú pháp và có thể được mở rộng bằng các trường bổ sung giống như mọi trường ParseObject khác.

FirebaseUser có một tập hợp các thuộc tính cơ bản cố định: một mã nhận dạng duy nhất, một địa chỉ email chính tên và URL ảnh được lưu trữ trong cơ sở dữ liệu người dùng của một dự án riêng biệt; bạn có thể cập nhật các thuộc tính đó bằng cách người dùng. Bạn không thể trực tiếp thêm các thuộc tính khác vào đối tượng FirebaseUser; thay vào đó, bạn có thể lưu trữ các thuộc tính bổ sung trong Firebase Realtime Database.

Sau đây là ví dụ về cách bạn có thể đăng ký người dùng và thêm trường số điện thoại bổ sung.

Phân tích cú pháp
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());
            }
        }
    });

Chiến lược di chuyển được đề xuất

Di chuyển tài khoản

Để di chuyển tài khoản người dùng từ Phân tích cú pháp sang Firebase, hãy xuất cơ sở dữ liệu người dùng của bạn sang tệp JSON hoặc CSV, sau đó nhập tệp này vào dự án Firebase bằng cách sử dụng auth:import của Firebase CLI .

Trước tiên, hãy xuất cơ sở dữ liệu người dùng của bạn từ bảng điều khiển Phân tích cú pháp hoặc dịch vụ tự lưu trữ của bạn cơ sở dữ liệu. Ví dụ: một tệp JSON được xuất từ bảng điều khiển Phân tích cú pháp có thể có dạng như sau:

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

Sau đó, chuyển đổi tệp được xuất sang định dạng mà Firebase yêu cầu CLI. Sử dụng objectId của người dùng Phân tích cú pháp làm localId người dùng Firebase của bạn. Ngoài ra, base64 mã hoá Các giá trị bcryptPassword qua Trình phân tích cú pháp và sử dụng các giá trị đó trong passwordHash . Ví dụ:

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

Cuối cùng, hãy nhập tệp đã chuyển đổi bằng Firebase CLI, chỉ định bcrypt làm thuật toán băm:

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

Di chuyển dữ liệu người dùng

Nếu đang lưu trữ thêm dữ liệu cho người dùng của mình, bạn có thể di chuyển dữ liệu đó sang Firebase Realtime Database bằng cách sử dụng các chiến lược được mô tả trong phần di chuyển dữ liệu. Nếu bạn di chuyển tài khoản bằng quy trình được mô tả trong phần di chuyển tài khoản, Các tài khoản Firebase có cùng mã nhận dạng của tài khoản Parse, cho phép bạn dễ dàng di chuyển và tái tạo bất kỳ mối quan hệ nào được khoá bởi user id.

Firebase Cloud Messaging

Firebase Cloud Messaging (FCM) là một giải pháp nhắn tin đa nền tảng cho phép bạn đáng tin cậy gửi tin nhắn và thông báo mà không mất phí. Trình soạn thông báo là một dịch vụ miễn phí được phát triển trên Firebase Cloud Messaging để bật thông báo người dùng được nhắm mục tiêu cho các nhà phát triển ứng dụng dành cho thiết bị di động.

Hãy xem tài liệu về Firebase Cloud Messaging để tìm hiểu thêm.

Điểm khác biệt với thông báo đẩy phân tích cú pháp

Mỗi ứng dụng Phân tích cú pháp được cài đặt trên thiết bị đã đăng ký nhận thông báo sẽ có Đối tượng Installation là nơi bạn lưu trữ tất cả dữ liệu cần thiết để nhắm mục tiêu thông báo. Installation là một lớp con của ParseUser, tức là bạn có thể thêm mọi dữ liệu bổ sung mà bạn muốn cho các thực thể Installation.

Trình soạn thông báo cung cấp các phân khúc người dùng được xác định trước dựa trên thông tin như ứng dụng, phiên bản ứng dụng và thiết bị ngôn ngữ. Bạn có thể tạo những phân khúc người dùng phức tạp hơn bằng cách sử dụng các sự kiện và thuộc tính Google Analytics để tạo đối tượng. Xem đối tượng để tìm hiểu thêm. Những thông tin nhắm mục tiêu này sẽ không xuất hiện trong Firebase Realtime Database.

Chiến lược di chuyển được đề xuất

Di chuyển mã thông báo của thiết bị

Tại thời điểm viết bài, Phân tích cú pháp Android SDK sử dụng phiên bản FCM cũ hơn mã thông báo đăng ký, không tương thích với các tính năng do trình soạn Thông báo cung cấp.

Bạn có thể nhận mã thông báo mới bằng cách thêm SDK FCM vào ứng dụng của mình; tuy nhiên, thao tác này có thể vô hiệu hoá mã thông báo mà SDK phân tích cú pháp sử dụng để nhận thông báo. Nếu muốn tránh trường hợp đó, bạn có thể thiết lập SDK Phân tích cú pháp để sử dụng cả mã nhận dạng người gửi của Phân tích cú pháp và mã nhận dạng người gửi của bạn. Bằng cách này, bạn không vô hiệu hoá mã thông báo mà SDK phân tích cú pháp sử dụng, nhưng lưu ý rằng giải pháp này sẽ ngừng hoạt động khi Phân tích cú pháp tắt dự án.

Đang di chuyển kênh sang FCM chủ đề

Nếu đang sử dụng các kênh Phân tích cú pháp để gửi thông báo, thì bạn có thể di chuyển sang chủ đề FCM. Các chủ đề này cung cấp cho bạn có cùng mô hình nhà xuất bản và người đăng ký. Để xử lý quá trình chuyển đổi từ Phân tích cú pháp sang FCM, bạn có thể viết một phiên bản mới của ứng dụng dùng SDK Phân tích cú pháp để huỷ đăng ký các kênh Phân tích cú pháp và SDK FCM để đăng ký chủ đề FCM tương ứng. Trong phiên bản này của ứng dụng, bạn nên tắt tính năng nhận thông báo phân tích cú pháp SDK, hãy xoá nội dung sau khỏi tệp kê khai của ứng dụng:

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

Ví dụ: nếu người dùng của bạn đăng ký kênh "Người khổng lồ" topic, bạn sẽ làm một số việc như:

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

Khi sử dụng chiến lược này, bạn có thể gửi thông báo đến cả kênh Phân tích cú pháp và Chủ đề FCM, hỗ trợ người dùng cả phiên bản cũ và phiên bản mới. Khi đã đủ người dùng di chuyển từ Phiên bản chỉ phân tích cú pháp của ứng dụng, bạn có thể ngừng cung cấp phiên bản đó và bắt đầu gửi chỉ bằng FCM.

Xem Tài liệu về FCM chủ đề để tìm hiểu thêm.

Firebase Remote Config

Firebase Remote Config là dịch vụ đám mây cho phép bạn thay đổi hành vi và giao diện của mà không yêu cầu người dùng tải bản cập nhật ứng dụng xuống. Khi sử dụng Cấu hình từ xa, bạn tạo trong ứng dụng các giá trị mặc định kiểm soát hành vi và giao diện của ứng dụng. Sau đó, bạn có thể sử dụng bảng điều khiển của Firebase để ghi đè các giá trị mặc định trong ứng dụng cho tất cả người dùng ứng dụng hoặc cho các phân khúc trong cơ sở người dùng của bạn.

Firebase Remote Config có thể rất hữu ích trong quá trình di chuyển nếu bạn muốn kiểm thử giải pháp khác nhau và có thể linh động chuyển nhiều khách hàng sang nhà cung cấp khác. Ví dụ: nếu có một phiên bản ứng dụng sử dụng cả Firebase và Phân tích cú pháp cho dữ liệu, bạn có thể dùng quy tắc phần trăm ngẫu nhiên để xác định khách hàng nào đọc từ Firebase và tăng dần tỷ lệ phần trăm.

Để tìm hiểu thêm về Firebase Remote Config, hãy xem Giới thiệu về Remote Config.

Điểm khác biệt với cấu hình phân tích cú pháp

Với cấu hình Phân tích cú pháp, bạn có thể thêm các cặp khoá/giá trị vào ứng dụng của mình trên Trang tổng quan về cấu hình phân tích cú pháp, sau đó tìm nạp ParseConfig trên máy khách. Mỗi phiên bản ParseConfig mà bạn get luôn là bất biến. Khi bạn truy xuất một ParseConfig mới trong tương lai từ mạng, nó sẽ không sửa đổi bất kỳ phiên bản ParseConfig hiện có nào, mà thay vào đó hãy tạo một tài khoản mới và cung cấp tài khoản đó qua getCurrentConfig().

Với Firebase Remote Config, bạn tạo các chế độ mặc định trong ứng dụng cho các cặp giá trị/khoá mà bạn có thể ghi đè từ bảng điều khiển của Firebase, đồng thời bạn có thể sử dụng các quy tắc và điều kiện để cung cấp các biến thể về trải nghiệm người dùng đến các phân khúc khác nhau trong cơ sở người dùng của bạn. Firebase Remote Config triển khai một singleton giúp bạn có thể sử dụng các cặp khoá/giá trị cho ứng dụng. Ban đầu, singleton trả về các giá trị mặc định mà bạn xác định trong ứng dụng. Bạn có thể tìm nạp một bộ giá trị mới từ máy chủ bất cứ lúc nào thuận tiện cho ứng dụng của bạn; sau khi tìm nạp thành công tập hợp mới, bạn có thể chọn thời điểm kích hoạt để cung cấp các giá trị mới cho ứng dụng.

Chiến lược di chuyển được đề xuất

Bạn có thể di chuyển sang Firebase Remote Config bằng cách sao chép các cặp khoá/giá trị của cấu hình Phân tích cú pháp vào bảng điều khiển của Firebase, sau đó triển khai phiên bản mới của ứng dụng sử dụng Firebase Remote Config.

Nếu muốn thử nghiệm với cả Cấu hình phân tích cú pháp và Firebase Remote Config, bạn có thể triển khai một phiên bản mới của ứng dụng sử dụng cả hai SDK cho đến khi đủ số người dùng di chuyển từ phiên bản chỉ Phân tích cú pháp.

So sánh mã

Phân tích cú pháp

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