Cloud Firestore'da varlık oluşturun

Oluşturduğunuz uygulamanın türüne bağlı olarak, hangi kullanıcılarınızın veya cihazlarınızın aktif olarak çevrimiçi olduğunu tespit etmeyi yararlı bulabilirsiniz; diğer bir deyişle "varlık durumunu" tespit etmek olarak bilinir.

Örneğin, sosyal ağ gibi bir uygulama oluşturuyorsanız veya bir IoT cihaz filosu dağıtıyorsanız, bu bilgiyi çevrimiçi olan ve sohbet etmekte özgür olan arkadaşlarınızın listesini görüntülemek veya IoT cihazlarınızı "son görülme"ye göre sıralamak için kullanabilirsiniz. "

Cloud Firestore, yerel olarak varlığı desteklemez ancak bir varlık sistemi oluşturmak için diğer Firebase ürünlerinden yararlanabilirsiniz.

Çözüm: Gerçek Zamanlı Veritabanıyla Bulut İşlevleri

Cloud Firestore'u Firebase Realtime Database'in yerel varlık özelliğine bağlamak için Cloud Functions'ı kullanın.

Bağlantı durumunu raporlamak için Gerçek Zamanlı Veritabanını kullanın, ardından bu verileri Cloud Firestore'a yansıtmak için Cloud Functions'ı kullanın.

Gerçek Zamanlı Veritabanında varlığı kullanma

İlk olarak, geleneksel bir varlık sisteminin Gerçek Zamanlı Veritabanında nasıl çalıştığını düşünün.

// Fetch the current user's ID from Firebase Authentication.
var uid = firebase.auth().currentUser.uid;

// Create a reference to this user's specific status node.
// This is where we will store data about being online/offline.
var userStatusDatabaseRef = firebase.database().ref('/status/' + uid);

// We'll create two constants which we will write to 
// the Realtime database when this device is offline
// or online.
var isOfflineForDatabase = {
    state: 'offline',
    last_changed: firebase.database.ServerValue.TIMESTAMP,
};

var isOnlineForDatabase = {
    state: 'online',
    last_changed: firebase.database.ServerValue.TIMESTAMP,
};

// Create a reference to the special '.info/connected' path in 
// Realtime Database. This path returns `true` when connected
// and `false` when disconnected.
firebase.database().ref('.info/connected').on('value', function(snapshot) {
    // If we're not currently connected, don't do anything.
    if (snapshot.val() == false) {
        return;
    };

    // If we are currently connected, then use the 'onDisconnect()' 
    // method to add a set which will only trigger once this 
    // client has disconnected by closing the app, 
    // losing internet, or any other means.
    userStatusDatabaseRef.onDisconnect().set(isOfflineForDatabase).then(function() {
        // The promise returned from .onDisconnect().set() will
        // resolve as soon as the server acknowledges the onDisconnect() 
        // request, NOT once we've actually disconnected:
        // https://firebase.google.com/docs/reference/js/firebase.database.OnDisconnect

        // We can now safely set ourselves as 'online' knowing that the
        // server will mark us as offline once we lose connection.
        userStatusDatabaseRef.set(isOnlineForDatabase);
    });
});

Bu örnek, eksiksiz bir Gerçek Zamanlı Veritabanı varlık sistemidir. Birden fazla bağlantı kesilmesi, çökme vb. sorunları giderir.

Cloud Firestore'a bağlanma

Cloud Firestore'da benzer bir çözümü uygulamak için aynı Realtime Database kodunu kullanın, ardından Realtime Database ile Cloud Firestore'u senkronize tutmak için Cloud Functions'ı kullanın.

Henüz yapmadıysanız projenize Gerçek Zamanlı Veritabanı ekleyin ve yukarıdaki varlık çözümünü ekleyin.

Daha sonra aşağıdaki yöntemlerle iletişim durumunu Cloud Firestore ile senkronize edeceksiniz:

  1. Yerel olarak, uygulamanın çevrimdışı olduğunu bilmesi için çevrimdışı cihazın Cloud Firestore önbelleğine.
  2. Global olarak, Cloud Firestore'a erişen diğer tüm cihazların bu belirli cihazın çevrimdışı olduğunu bilmesi için bir Bulut İşlevi kullanmak.

Cloud Firestore'un yerel önbelleğini güncelleme

İlk sorunu gerçekleştirmek için gereken değişikliklere bir göz atalım: Cloud Firestore'un yerel önbelleğinin güncellenmesi.

// ...
var userStatusFirestoreRef = firebase.firestore().doc('/status/' + uid);

// Firestore uses a different server timestamp value, so we'll 
// create two more constants for Firestore state.
var isOfflineForFirestore = {
    state: 'offline',
    last_changed: firebase.firestore.FieldValue.serverTimestamp(),
};

var isOnlineForFirestore = {
    state: 'online',
    last_changed: firebase.firestore.FieldValue.serverTimestamp(),
};

firebase.database().ref('.info/connected').on('value', function(snapshot) {
    if (snapshot.val() == false) {
        // Instead of simply returning, we'll also set Firestore's state
        // to 'offline'. This ensures that our Firestore cache is aware
        // of the switch to 'offline.'
        userStatusFirestoreRef.set(isOfflineForFirestore);
        return;
    };

    userStatusDatabaseRef.onDisconnect().set(isOfflineForDatabase).then(function() {
        userStatusDatabaseRef.set(isOnlineForDatabase);

        // We'll also add Firestore set here for when we come online.
        userStatusFirestoreRef.set(isOnlineForFirestore);
    });
});

Bu değişikliklerle artık yerel Cloud Firestore durumunun her zaman cihazın çevrimiçi/çevrimdışı durumunu yansıtmasını sağladık. Bu, /status/{uid} belgesini dinleyebileceğiniz ve kullanıcı arayüzünüzü bağlantı durumunu yansıtacak şekilde değiştirmek için verileri kullanabileceğiniz anlamına gelir.

userStatusFirestoreRef.onSnapshot(function(doc) {
    var isOnline = doc.data().state == 'online';
    // ... use isOnline
});

Cloud Firestore'u küresel olarak güncelleme

Uygulamamız çevrimiçi varlığı kendisine doğru bir şekilde rapor etse de, "çevrimdışı" durum yazma işlemimiz yalnızca yerel olduğundan ve bağlantı yeniden kurulduğunda senkronize edilmediğinden bu durum diğer Cloud Firestore uygulamalarında henüz doğru olmayacaktır. Buna karşı koymak için Gerçek Zamanlı Veritabanındaki status/{uid} yolunu izleyen bir Bulut İşlevi kullanacağız. Gerçek Zamanlı Veritabanı değeri değiştiğinde, tüm kullanıcıların durumlarının doğru olması için değer Cloud Firestore ile senkronize edilir.

Node.js

firebase.firestore().collection('status')
    .where('state', '==', 'online')
    .onSnapshot(function(snapshot) {
        snapshot.docChanges().forEach(function(change) {
            if (change.type === 'added') {
                var msg = 'User ' + change.doc.id + ' is online.';
                console.log(msg);
                // ...
            }
            if (change.type === 'removed') {
                var msg = 'User ' + change.doc.id + ' is offline.';
                console.log(msg);
                // ...
            }
        });
    });

Bu işlevi dağıttığınızda, Cloud Firestore ile çalışan eksiksiz bir varlık sistemine sahip olacaksınız. Aşağıda, where() sorgusunu kullanarak çevrimiçi olan veya çevrimdışı olan tüm kullanıcılar için bir izleme örneği verilmiştir.

firebase.firestore().collection('status')
    .where('state', '==', 'online')
    .onSnapshot(function(snapshot) {
        snapshot.docChanges().forEach(function(change) {
            if (change.type === 'added') {
                var msg = 'User ' + change.doc.id + ' is online.';
                console.log(msg);
                // ...
            }
            if (change.type === 'removed') {
                var msg = 'User ' + change.doc.id + ' is offline.';
                console.log(msg);
                // ...
            }
        });
    });

Sınırlamalar

Cloud Firestore uygulamanıza varlık eklemek için Gerçek Zamanlı Veritabanını kullanmak ölçeklenebilir ve etkilidir ancak bazı sınırlamaları vardır:

  • Geri dönme - Cloud Firestore'da gerçek zamanlı değişiklikleri dinlerken bu çözümün birden fazla değişikliği tetiklemesi muhtemeldir. Bu değişiklikler istediğinizden daha fazla olayı tetiklerse Cloud Firestore olaylarını manuel olarak iptal edin.
  • Bağlantı - bu uygulama, Cloud Firestore'a değil, Gerçek Zamanlı Veritabanına olan bağlantıyı ölçer. Her veritabanının bağlantı durumu aynı değilse bu çözüm yanlış bir iletişim durumu bildirebilir.
  • Android - Android'de, Gerçek Zamanlı Veritabanının 60 saniyelik işlem yapılmaması durumunda arka uçla bağlantısı kesilir. Hareketsizlik, açık dinleyicilerin veya bekleyen işlemlerin olmadığı anlamına gelir. Bağlantıyı açık tutmak için yola .info/connected dışında bir değer olay dinleyicisi eklemenizi öneririz. Örneğin, her oturumun başında FirebaseDatabase.getInstance().getReference((new Date()).toString()).keepSynced() yapabilirsiniz. Daha fazla bilgi için bkz . Bağlantı Durumunu Algılama .