Reputation: 65978
Could you tell me how to detect changes in Firestore db node within client side code (.ts
file)? I know how to do that using cloud functions. But how can I do that within client side code?
Firestore Node: projects/{id}/transactions/
My requirement is this: I need to upgrade provider's(i.e. projectProvider
) shared property value if there is any change on above node. How can I do that?
As an example:
onWrite
event is perfectly fit on my use case. But how can I implement it inside client .ts
file?
This is a node.js
implementation of cloud function. How can I do such implementation on client .ts
file?
// Listen for any change on document `marie` in collection `users`
exports.myFunctionName = functions.firestore
.document('users/marie').onWrite((change, context) => {
// ... Your code here
});
Note: I use angularfire2
with my ionic 3
app.
Upvotes: 1
Views: 2128
Reputation: 16276
Step 1. In firestore, make a notification doc for whatever information you want to notify the client side. Something like this:
db.collection('notifications').doc('transactionHappened').set({/*your transaction details*/});
Step 2. Register to your notification doc and listen to it, e.g. when you are writing to a transaction doc, also write your latest transaction info into the transactionHappened doc:
const yourHandler = data=>{/*handle your notification details here*/};
db.collection('notifications').doc('transactionHappened').onSnapshot(yourHandler);
Step 3. Now onSnapshot
is registered, but if your app was disconnected it doesn't catch any notifications during that period. Let's handle it.
const reconnectHandler =()=>{/*you were offline, so read whatever you need from firestore to cath up with the latest data*/};
const disconnectHandler =()=>{/*display something on your screen to indicate it is offline*/};
const monitorNetwork=()=> {
let status = true;
const timeout = ()=> setTimeout(()=>{
if(status !== navigator.onLine) {
status = navigator.onLine;
console.log(`Network is ${status? 'up 🠕':'down 🠗'}`);
if (status) { //if network is flipped to online
reconnectHandler();
} else {//just went offline
disconnectHandler();
}
}
timeout();
}, 1000);
timeout();
}
The little function above will create a heartbeat for you every 1 second to monitor your network status.
Upvotes: 0
Reputation: 4908
The following code will allow you to listen to a single collection. There is currently no way to listen to sub-collections across multiple project documents. The best solution to this would be to de-normalise your data model, so that you have a collection called projectTransactions
and filter client queries with a projectId
field and enforce access with security rules.
The code uses the docChanges
method, which allows you to view only changes made to the collection without having to go through each document. This approach is discussed in the "View changes between snapshots" section of the documentation when it says
It is often useful to see the actual changes to query results between query snapshots, instead of simply using the entire query snapshot.
const firebase = require('firebase');
require("firebase/firestore");
// Initialize Firebase
let config = {
apiKey: "*** Your API key ***",
authDomain: "*** Your Auth domain ***",
databaseURL: "*** Your database URL ***",
projectId: "*** Your project ID ***",
messagingSenderId: "*** Your Messaging Sender ID ***"
};
firebase.initializeApp(config);
let email = '[email protected]';
let password = 'myExamplePassword';
firebase.auth().signInWithEmailAndPassword(email, password)
.catch(error => {
console.log(error);
});
firebase.auth().onAuthStateChanged((user) => {
if (user) {
console.log('I am logged in');
// Initialise Firestore
const firestore = firebase.firestore();
const settings = {timestampsInSnapshots: true};
firestore.settings(settings);
return firestore
.collection('projectTransactions')
.onSnapshot((querySnapshot) => {
console.log('Listening to the projectTransactions collection');
querySnapshot.docChanges().forEach((change) => {
// A new transaction has been added
if (change.type === 'added') {
console.log(`A new transaction has been added with ID: ${change.doc.id}`);
}
// A transaction has been deleted
if (change.type === 'removed') {
console.log(`A transaction has been removed with ID: ${change.doc.id}`);
}
});
});
} else {
// User is signed out.
// ...
}
});
Upvotes: 1