Cloud Firestore'da varlık oluşturun

Geliştirdiğiniz uygulamanın türüne bağlı olarak, hangi kullanıcılarınızın veya cihazlarınızın etkin olarak internete bağlı olduğunu algılamayı (başka bir deyişle "mevcudiyeti" algılamayı) yararlı bulabilirsiniz.

Örneğin, sosyal ağ gibi bir uygulama geliştiriyorsanız veya bir IoT cihazı filosu dağıtıyorsanız bu bilgileri kullanarak sohbet etmeye hazır olan ve online olan arkadaşların listesini görüntüleyebilir veya IoT cihazlarınızı "son görüntülenme"ye göre sıralayabilirsiniz.

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

Çözüm: Cloud Functions with Realtime Database

Cloud Firestore uygulamasını Firebase Realtime Database'in yerel ağına bağlamak için Cloud Functions'ı kullanın.

Bağlantı durumunu bildirmek için Realtime Database'i, bu verileri Cloud Firestore'e yansıtmak için Cloud Functions'ı kullanın.

Realtime Database'de varlığı kullanma

Öncelikle geleneksel varlık gösterme sisteminin Realtime Database'de nasıl çalıştığını düşünün.

Web

// 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 Realtime Database varlığı sistemidir. Bu sayfa, bağlantı kesintileri, kilitlenmeler vb. olabilir.

Cloud Firestore cihazına bağlanıyor

Cloud Firestore ürününde benzer bir çözümü uygulamak için aynı Cloud Functions'ı kullanarak Realtime Database'i koruyabilir ve Cloud Firestore senkronize.

Henüz yapmadıysanız projenize Realtime Database'i ekleyin ve yukarıdaki varlık çözümü çözümünü içermelidir.

Ardından, evde olma durumunu şununla senkronize edin: Cloud Firestore aşağıdaki yöntemleri kullanabilirsiniz:

  1. Yerel olarak, çevrimdışı cihazın Cloud Firestore önbelleğine. Böylece uygulama çevrimdışı olduğunu bilir.
  2. Cloud Firestore'e erişen diğer tüm cihazların bu cihazın çevrimdışı olduğunu bilmesi için Cloud işlevi kullanılarak dünya genelinde.

Cloud Firestore adlı cihazın yerel önbelleği güncelleniyor

Şimdi, ilk sorunu gerçekleştirmek için gereken değişikliklere bakalım - güncelleme Cloud Firestore adlı cihazın yerel önbelleği.

Web

// ...
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 birlikte, yerel Cloud Firestore durumunun her zaman cihazın çevrimiçi/çevrimdışı durumunu yansıtmasını sağladık. Bu sayede /status/{uid} belgesini dinleyebilir ve verileri kullanarak kullanıcı arayüzünüzü bağlantı durumunu yansıtacak şekilde değiştirebilirsiniz.

Web

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

Cloud Firestore'ü dünya genelinde güncelleme

Uygulamamız çevrimiçi varlığı doğru bir şekilde kendisine bildirse de, bu durum "çevrimdışı" etiketimiz diğer Cloud Firestore uygulamalarda doğru durum yazma yalnızca yereldir ve bağlantı tekrar kurulduğunda senkronize edilmez. Karşı göndermek için Bunun için status/{uid} yolunu Gerçek Zamanlı olarak izleyen bir Cloud Functions işlevi kullanacağız. Veritabanı. 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ıktan sonra eksiksiz bir varlık sistemiyle çalışır durumda olursunuz Cloud Firestore ile birlikte. Aşağıda, where() sorgusu kullanılarak çevrimiçi olan veya çevrimdışı olan tüm kullanıcılar için izleme örneği verilmiştir.

Web

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 Realtime Database'i kullanmak ancak bazı sınırlamaları vardır:

  • Debouncing: Cloud Firestore'deki gerçek zamanlı değişiklikleri dinlerken bu çözümün birden fazla değişikliği tetikleme olasılığı vardır. Bu değişiklikler istediğinizden daha fazla etkinlik tetiklerse Cloud Firestore etkinliklerini manuel olarak debounce edin.
  • Bağlantı: Bu uygulama, Cloud Firestore'ye değil, Gerçek Zamanlı Veritabanı'na olan bağlantıyı ölçer. Bağlantı her veritabanındaki durum aynı değilse bu çözüm, evde olma durumu yanlış.
  • Android: Android'de, Realtime Database ile arka uçta 60 saniye boyunca işlem yapılmadığında ortaya çıkar. Etkinlik olmaması, açık dinleyicilerin olmadığı anlamına gelir veya bekleyen işlemler. Bağlantıyı açık tutmak için .info/connected dışındaki bir yolun değer etkinliği işleyicisi. Örneğin, FirebaseDatabase.getInstance().getReference((new Date()).toString()).keepSynced() yapabilir her oturumun başlangıcında. Daha fazla bilgi için bkz. Bağlantı Durumunu Algılama.