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 oluşturuyorsanız veya bu bilgileri kullanarak kullanıcılarınızın yaşam döngüsünü veya IoT cihazlarınızı şöyle sıralayarak "son görülmedi."

Cloud Firestore, evde olma özelliğini yerel olarak desteklemez, ancak siz de yapabilirsiniz varlık sistemi oluşturmak için diğer Firebase ürünlerinden yararlanın.

Çö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ık 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ık sistemidir. Bu sayfa, bağlantı kesintileri, kilitlenmeler vb. olabilir.

Cloud Firestore cihazına bağlanıyor

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

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

Ardından, aşağıdaki yöntemlerden birini kullanarak mevcut durumla Cloud Firestore durumunu senkronize edin:

  1. Yerel olarak, uygulamanın çevrimdışı cihaz Cloud Firestore önbelleğine çevrimdışı olduğunu bilir.
  2. Diğer tüm cihazların erişebilmesi için dünya genelinde bir Cloud Functions işlevi Cloud Firestore bu cihazın çevrimdışı olduğunu biliyor.

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

İlk sorunu gidermek için gereken değişikliklere (Cloud Firestore'ın yerel önbelleğini güncelleme) göz atalım.

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 artık yerel Cloud Firestore durumunun her zaman cihazın çevrimiçi/çevrimdışı durumunu yansıtır. Bu da size sunulan Kullanıcı arayüzünüzü bağlantıyı yansıtacak şekilde değiştirmek için /status/{uid} dokümanı ve verileri kullanın durumu.

Web

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

Cloud Firestore genel olarak güncelleniyor

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ğıdaki örnekte, satın alma işlemi gerçekleştiren kullanıcılar için internete girme veya where() sorgusu kullanarak çevrimdışı olma.

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 kullanılabilirlik özelliği eklemek için Realtime Database'i kullanmak ölçeklenebilir ve etkilidir ancak bazı sınırlamaları vardır:

  • Azaltma: Gerçek zamanlı değişiklikleri dinlerken Cloud Firestore, bu çözüm muhtemelen birden fazla anlamına gelir. Bu değişiklikler istediğinizden daha fazla etkinliği tetiklerse manuel olarak Cloud Firestore etkinliklerinin geri kalanını iptal et.
  • Bağlantı: Bu uygulama, gerçek zamanlı bağlantıyı ölçer Veritabanı, Cloud Firestore ile değil. Her veritabanına ait bağlantı durumu aynı değilse bu çözüm yanlış bir varlık durumu bildirebilir.
  • 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ışında bir yola değer etkinliği işleyici 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.