Flutter Firebase Cloud Functions deleting all items as soon as they are written - firebase

I'm trying to use the deleteOldItems Cloud Functions code for my project, when I use the code and simply change the 2 hours to 4 it deletes all my nodes as soon as they are written. Here is my Firebase functions code...
exports.deleteOldItems = functions.database.ref('messages/{pushId}').onWrite(async (change) => {
var ref = change.after.ref.parent; // reference to the items
var now = Date.now();
var cutoff = now - 4 * 60 * 60 * 1000;
var oldItemsQuery = ref.orderByChild('timestamp').endAt(cutoff);
return oldItemsQuery.once('value', function(snapshot) {
// create a map with all children that need to be removed
var updates = {};
snapshot.forEach(function(child) {
updates[child.key] = null
});
// execute all updates in one go and return the result to end the function
return ref.update(updates);
});
});
And here is how I'm saving my timestamp in Flutter to
database/messages
with child 'timestamp'..
var time = DateTime.now().millisecondsSinceEpoch;
Here is my JSON # 'messages'
"messages" : {
"-M3e5Glv5JEaz12hDwBB" : {
"body" : "Hello",
"name" : "Charles",
"photo" : "https://media1.giphy.com/media/7wDEaTbCupuRq/giphy-downsized.gif",
"timeStamp" : 1585549220985,
"user" : "4eb8920a-e407-4488-bce4-c6f64f7b0891"
},
"-M3e5Jfx2cnbtMTNLPev" : {
"body" : "Example",
"name" : "Charles",
"photo" : "https://media1.giphy.com/media/7wDEaTbCupuRq/giphy-downsized.gif",
"timeStamp" : 1585549232893,
"user" : "4eb8920a-e407-4488-bce4-c6f64f7b0891"
},
"-M3e6oYk6_zTe6IAs0Fg" : {
"bodyGif" : "https://media3.giphy.com/media/8xomIW1DRelmo/giphy.gif",
"name" : "Charles",
"photo" : "https://media1.giphy.com/media/7wDEaTbCupuRq/giphy-downsized.gif",
"timestamp" : 1585549625584,
"user" : "4eb8920a-e407-4488-bce4-c6f64f7b0891"
},
"-M3hR_DrGcKhM8zpFbYA" : {
"body" : "Again",
"name" : "Charles",
"photo" : "https://media1.giphy.com/media/7wDEaTbCupuRq/giphy-downsized.gif",
"timeStamp" : 1585605399479,
"user" : "4eb8920a-e407-4488-bce4-c6f64f7b0891"
}
and my database security rules are as follows for 'messages'...
"messages": {
".indexOn": ["timestamp"]
}
How can I get the nodes to be removed as expected?

Related

firebase realtime database to update an entry after filter using angularfire 2

The data in the realtime db is structure like below:
"orders" : {
"-LM5p4tl7Og_PMJOspZ-" : {
"customer" : {
"_name" : "Vik Kumar",
"_uid" : "oSEYj0zrkhPCk9r7uwyOOkHcqe53"
},
"order" : {
"_orderNumber" : "VikKumar-26954",
"_orderStatus" : "Pending",
"_orderTotal" : 500,
}
},
"-LM5s1wRCvqWA1vsZONy" : {
"customer" : {
"_name" : "Vik Kumar",
"_uid" : "oSEYj0zrkhPCk9r7uwyOOkHcqe53"
},
"order" : {
"_orderNumber" : "VikKumar-11423",
"_orderStatus" : "Pending",
"_orderTotal" : 500,
}
},
"-LM5sOHzjLeqFGFleMxq" : {
"customer" : {
"_name" : "Vik Kumar",
"_uid" : "oSEYj0zrkhPCk9r7uwyOOkHcqe53"
},
"order" : {
"_orderNumber" : "VikKumar-63772",
"_orderStatus" : "Pending",
"_orderTotal" : 500,
}
}
}
I am using angularfire2 in my ionic app and filtering few orders as below:
getPendingOrders(dateStr:string){
return new Promise((resolve, reject) =>
{
this.db.list('orders',
ref => ref.orderByChild("order/_date").equalTo(dateStr)
).valueChanges().subscribe(
res => {
resolve(res)
},
err => {
console.log(err)
reject(err)
}
)
})
}
The above query gives me the response as below
[{"customer": {}, "order": {}}, {"customer": {}, "order": {}}]
I can render it in UI just fine and i want the end user to be able to update the value of property "_orderStatus". The trouble is the way i queried the data i have lost the keys to identify a particular object to update it. Please advise
ok, not sure if this helps,I think you have migrated to use AngularFire 5.0. Calling .valueChanges() will return an Observable without any metadata (item key for example), you need to use .snapshotChanges() call instead:
this.db.list(...)
.snapshotChanges()
.map(changes => {
return changes.map(change => ({key: change.payload.key, ...change.payload.val()}));
})
.subscribe(...)

How do you get the node which contains a certain attribute in Firebase?

For example - How to get the node -L1BchvA8NaQ9Yh7CjS_ which matches email = tomcruise#firebasemyapp.com? when the database looks like
{
"-L1BchvA8NaQ9Yh7CjS_" : {
"createdAt" : 1514187972592,
"displayName" : "tom cruise",
"email" : "tomcruise#firebasemyapp.com",
"firstName" : "tom",
"lastName" : "cruise",
"profileLink" : "https://reactjs.org/logo-og.png",
"status" : "happy christmas"
},
"-L1CcUEBOECrJJozlHJv" : {
"createdAt" : 1514204689673,
"displayName" : "Robert John Downey Jr",
"email" : "robertjohndowneyjr#firebasemyapp.com",
"firstName" : "Rober John",
"lastName" : "Downey Jr",
"profileLink" : "https://reactjs.org/logo-og.png",
"status" : "happy christmas"
},
}
Edit:-
I am using react-native.js.
You didn't mention what language you're using, but I'll answer in javascript and it shouldn't be difficult to change into a different language.
var database = firebase.database();
var rootRef = database.ref();
rootRef.orderByChild('email')
.equalTo('tomcruise#firebasemyapp.com')
.on('child_added')
.then(function(snapshot){
var result = snapshot.val();
//Do what you want with the result
});
I found solution from Common SQL Queries converted for the Firebase Database.
var currentUserUID = firebase.auth().currentUser.uid;
let dbRef = firebase.database().ref("ARUserProfiles/" + currentUserUID);
dbRef
.orderByChild("email")
.equalTo("tomcruise#firebasemyapp.com")
.once(
"value",
response => {
const val = response.val();
let responsePayload;
if (val) {
responsePayload = Object.entries(val);
console.log("ARUserProfiles :-", responsePayload);
}
},
error => {
console.log(error);
}
);

How to orderByChild in nested Child in angularfire?

My firebase database structure is as below. I would like to search with a particular "Info/Email", let's say "abc#abc.com".
{
"-KhWrBcYyMluJbK7QpnK" : {
"Info" : {
"Email" : "xyz#gmail.com"
},
"Settings" : {
"Status" : "Accepted"
}
},
"-KhX0tgQvDtDYqt4XRoL" : {
"Info" : {
"Email" : "abc#abc.com"
},
"Settings" : {
"Status" : "Accepted"
}
},
"-KhX1eo7uFnOxqncDXQ5" : {
"Info" : {
"Email" : "abc#abc.com"
},
"Settings" : {
"Status" : "Pending"
}
}
}
I added a rule too
"Invitation" : {
".indexOn": ["Info/Email","Settings/Status"]
}
My AngularFire code is as follows:
var rootRef = firebase.database().ref().child('Invitation');
var userInvitations = rootRef.child("Info").orderByChild("Email").equalTo("abc#abc.com");
var allInvitations = $firebaseArray(userInvitations);
But I am getting a FIREBASE WARNING: Using an unspecified index. Consider adding ".indexOn": "Email" at /Invitation/Info to your security rules for better performance. and of course I am not receiving any data.
What are the mistakes I made here? Also can I add multiple orderByChild, for example: if I want to find details of the record, which has "Info/Email" equal to "abc#abc.com" and "Settings/Status" equal to "Pending" ?
The Firebase API only allows you to filter children one level deep
So with reference to your data structure:
if it were to be this way,
{
"-KhWrBcYyMluJbK7QpnK" : {
"Email" : "xyz#gmail.com",
"Settings" : {
"Status" : "Accepted"
}
},
"-KhX0tgQvDtDYqt4XRoL" : {
"Email" : "abc#abc.com",
"Settings" : {
"Status" : "Accepted"
}
},
"-KhX1eo7uFnOxqncDXQ5" : {
"Email" : "abc#abc.com",
"Settings" : {
"Status" : "Pending"
}
}
}
You should write your rules this way instead.
"Invitation" : {
"Info" : {
".indexOn": "Email",
},
"Settings" : {
".indexOn": "Status",
}
}
Then you will be able to query the data
var allInvitations = [];
var rootRef = firebase.database().ref().child('Invitation');
var userInvitations = rootRef.orderByChild("Email").equalTo("abc#abc.com");
userInvitations.on('value', snap => {
var invitations = snap.val()
for (prop in invitations ) {
allInvitations.push(invitations[prop ]);
}
console.log(allInvitations);
})

Firebase Normalized Collection and Scroll not working

first the code
var baseRef = new $databaseFactory();
var childRegistration = baseRef.child("registrations/");
var childStudents = baseRef.child("students/");
$scope.scrollRef = new Firebase.util.Scroll(childRegistration,'registerDate');
var normRegisteredStudens = new Firebase.util.NormalizedCollection(
[childStudents, "student"],
[$scope.scrollRef, "registration"]
).select(
"student.id",
"student.avatarImg",
"registration.registerDate",
"registration.entryMethod"
).ref();
$scope.lastRegisteredStudents = $firebaseObject( normRegisteredStudens );
$scope.loadRegisteredStudents = function() {
$scope.scrollRef.scroll.next(1);
};
data structure
"registrations" : {
"STD32159500" : {
"entryMethod" : "web",
"registerDate" : 1447425200913
},
"STD32159501" : {
"entryMethod" : "web",
"registerDate" : 1447430433895
}
"students" : {
"STD32159500" : {
"avatarImg" : "students/default-avatar-male.png",
"id" : "STD32159500",
},
"STD32159501" : {
"avatarImg" : "students/default-avatar-female.png",
"id" : "STD32159501",
}
there is no error but i still no getting one by one registration value with the function "loadRegisteredStudents", instead of that, i get all results.
i get this on load web
STD32159500:
avatarImg: "students/default-avatar-male.png"
entryMethod: "web"
id: "STD32159500"
registerDate: 1447425200913
STD32159501:
avatarImg: "students/default-avatar-female.png"
entryMethod: "web"
id: "STD32159501"
registerDate: 1447430433895

Firebase querying data limitToLast

I am still working with previous API, however I just came across one little issue. I am trying to query data from Firebase based on the limitToLast(100), however the .val() of snapshot is always null.
Here is sample data structure of my Messaging:
“Messaging” :{
"10153530036627802" : {
"10155174395220402" : {
"LastUpdate" : 1429295238531,
"Messages" : {
"1428338024339" : {
"date" : 1428338024339,
"message" : "Yo",
"sender" : "Uksz"
},
"1428338024488" : {
"date" : 1428338024487,
"message" : "Yo",
"sender" : "Uksz"
},
"1429023827304" : {
"date" : 1429023827303,
"message" : "Fygh",
"sender" : "Uksz"
},
"1429023828469" : {
"date" : 1429023828468,
"message" : "Fygh",
"sender" : "Uksz"
},
"1429295238532" : {
"date" : 1429295238531,
"message" : "Hgh",
"sender" : "Uksz"
}
},
"Name" : "Matt",
"Picture" : "https://scontent.xx.fbcdn.net/xxxx"
},
NEXT_USER_ID
And my code is:
var firebaseRef = new Firebase ("https://xxxx.firebaseio.com/Messages/");
var messageRef = firebaseRef.child(userId).child(recipient).child("Messages");
var messagesRef2 = messageRef.limitToLast(10);
messagesRef2.on("value", function(snapshot){
console.log(snapshot.val())
})
Whenever I am getting snapshot.val(), its value is equal to null. Where did I go wrong?
Thanks,
Uksz

Resources