i am trying to get auto key with firebase functions.
event.data.key doesn't return the key. How can i listen isEnabled and when changed it true, add another data to notification ref with same key.
exports.sendNotificationWhenEnabled = functions.database.ref('/contents/{contentId}/isEnabled').onWrite(event => {
const isEnabled = event.data.val();
const contentId = event.data.key;
admin.database().ref('/contents/' + contentId).once('value', function(snapshot) {
console.log('Sending Notification to: ', contentId);
admin.database().ref('/notifications/' + contentId).push({
'asd': 'asd'
}).then(snapshot => {
console.log('finished');
});
});
return "FINISHED";
}
});
I found solution with event.params.contentId
Related
How do I make it so it does not just like the newest post and it will like the post that they clicked the like button on?
code:
postSearch.addEventListener("input", (ev) => {
async function findPosts() {
const postsRef = collection(firestore, "posts")
const q = query(postsRef, orderBy("createdAt"));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((post) => {
// doc.data() is never undefined for query doc snapshots
if (post.data().likes == undefined) {
post.data().likes = 0
}
function epicTest() {
let postData = {
description: post.data().description,
display_name: post.data().display_name,
createdAt: post.data().createdAt,
uid: post.data().uid,
title: post.data().title,
likes: post.data().likes + 1
}
console.log(post.id)
console.log(postData)
setDoc(doc(postsRef, post.id), postData)
console.log("this feature hasn't been added yet")
}
let items = querySnapshot.docs.map(post => {
if (post.data().title.includes(ev.target.value) || post.data().description.includes(ev.target.value)) {
return `<div id="postBox">
<h4 id="postName">${post.data().display_name}</h4>
<h1 id="postTitle">${post.data().title}</h1>
<h3 id="postDescription">${post.data().description}</h3>
<div id="likeContainer"><ion-icon name="thumbs-up-outline" id="likeBtn" onclick="epicTest()"></ion-icon><h3 id="likeCount">${post.data().likes}</h3></div>
</div>`
}
});
items.reverse()
postList.innerHTML = items.join('');
if (postList.innerText == "") {
postList.innerText = "no results found"
}
let likeBtn = document.querySelectorAll("#likeBtn")
likeBtn.forEach(item => {
item.addEventListener("click", (ev) => {
let postData = {
description: post.data().description,
display_name: post.data().display_name,
createdAt: post.data().createdAt,
uid: post.data().uid,
title: post.data().title,
likes: post.data().likes + 1
}
console.log(post.id)
console.log(postData)
setDoc(doc(postsRef, post.id), postData)
console.log("this feature hasn't been added yet")
})
})
});
}
findPosts()
})
The following example shows how you can use the function to run whenever a 'Like' button is clicked, check the below sample:
var postRef = new Firebase(firebaseURL + id);
postRef.child('like-count').once('value', function(snapshot) {
var currentLikes = snapshot.val() ? snapshot.val() : 0;
postRef.update({
'postID': id,
'like-count': currentLikes + 1
}, function(error) {
if (error) {
console.log('Data could not be saved:' + error);
} else {
console.log('Data saved successfully');
}
});
getLikeCount(id);
});
}
The basic idea behind this is to pass the post id as a parameter to the function that is called when clicking the like button.
Also check the following examples for similar implementations:
Like/Dislike function for Firebase
Creating like button using firestore and useeffect
Like-Dislike system using Firebase Database
How to implement like button concept
Like button functionality
I want to get the Key generated when I push data to Firebase database. I want to handle them with my own function,
So the issue is when the user fills the form he sends the data to our real-time DB, contained in this data are some images (optional), and I don't need to let the image object empty in DB, so how to handle this, and when the user needs to send an image I want to save this image in the same Order, not in New Order.
Node
Here is my function
handleOrder = () => {
const { nameOfProblem, description, userId, imageOfPrblem, providerId } = this.state;
const PushData = firebase.database().ref("request/" + providerId + "/" + userId + "/orders/");
const ref = firebase.storage().ref("users/" + userId + "/UserImageOrders/" + path);
let file = imageOfPrblem.uri;
const path = "img_" + imageOfPrblem.fileName;
var newOrderRef = PushData.push({
nameOfProblem: nameOfProblem,
description: description,
});
if (file) {
let keyG = newOrderRef.key; // Key Generated with .push()
PushData.child(keyG).update({ // didn't updated the key generated just add new element with new key !!
imageOfPrblem: imageOfPrblem
});
ref.put(file).then(() => {
console.log("File uploaded..")
});
}
}
handleImages = () => {
const options = {
title: "Select Images!",
storageOptions: {
skipBackup: true,
path: "images"
}
};
ImagePicker.showImagePicker(options, response => {
console.log("Response = ", response);
if (response.uri) {
this.setState({ imageOfPrblem: response });
}
if (response.didCancel) {
console.log("User cancelled image picker");
} else if (response.error) {
console.log("ImagePicker Error: ", response.error);
} else if (response.customButton) {
console.log("User tapped custom button: ", response.customButton);
alert(response.customButton);
}
});
};
This seems to work fine for me:
var ref = firebase.database().ref("/55912103");
var newChildRef = ref.push({ firstChild: true });
console.log("new key: "+newChildRef.key);
ref.child(newChildRef.key).update({ secondChild: true });
After running this code, I end up with this JSON in the new child whose key gets logged:
"-LdgLWu_wBNNicFlPDGj" : {
"firstChild" : true,
"secondChild" : true
}
Live demo: https://jsbin.com/hovoleh/edit?js,console
Live JSON: https://stackoverflow.firebaseio.com/55912103.json?print=pretty
Update: if you just want to write both the existing data and new data to a new location:
var newOrderRef = PushData.push({
nameOfProblem: nameOfProblem,
description: description,
});
if (file) {
let keyG = newOrderRef.key; // Key Generated with .push()
PushData.child(keyG).update({
nameOfProblem: nameOfProblem,
description: description,
imageOfPrblem: imageOfPrblem
});
ref.put(file).then(() => {
console.log("File uploaded..")
});
}
The push ID from any Firebase snapshot ref is in ref.name().
I know it's been a while since the author created a post but maybe someone will find it useful.
The above answers are a bit wrong because, for example, after: newChildRef
var ref = firebase.database().ref("/55912103");
var newChildRef = ref.push({ firstChild: true });
newChildRef <--- promise
ref = rdb.ref('name_of_your_ref');
var childRef = ref.push({
IdUser: currentUserId,
ProductCategory: pCategory,
ProductDescription: pDesc,
ProductId: pId,
ProductName: pName,
ProductPrice: pPrice,
ProductQuantity: pQuan
}).catch(err => console.log(err.message));
childRef.then(item => {
ref.child(item.key).update({
IdKey: item.key
}).then(() => history.push('/delivery/basket'));
});
Greetings, Matthew
I'm new to react native and I'm working on firebase push notification. I'm getting the notification, but the problem is I'm not able to fetch data and display it in flatlist. Notification are shown perfectly. But the problem is why I can't fetch data. I want this event data to be fteched in my notification list which i have added below image.
componentWillMount() {
const firebase = require("firebase");
if (!firebase.apps.length) {
firebase.initializeApp(db);
}
this.fetchEventsList()
}
// Fetch events list
fetchEventsList = () => {
Preference.set('userPhoneCheck', '+917508060520');
let phone = Preference.get('userPhoneCheck');
firebase.database().ref('/users').child(phone).child('/events').once('value').then((snapshot) => {
let data = snapshot.val();
let items = Object.values(data);
this.setState({
userEventsList: items
});
// this.deleteOldEvents();
this.initAllEventList();
}).then((data) => {}).catch((error) => {
//error callback
console.log('error ', error)
})
}
//fetch the friends list according to group name
initAllEventList = () => {
//let groupName='G1';
let eventId = '';
let userEventsList = [...this.state.userEventsList];
for (var i = 0; i < userEventsList.length; i++) {
eventId = userEventsList[i].eventId;
ToastAndroid.show("eventId>" + eventId, ToastAndroid.SHORT);
if (eventId != '') {
this.fetchFriendsList(eventId);
}
}
}
//app users remove that not in contacts
fetchFriendsList = (eventId) => {
let allEventsList = [...this.state.allEventsList];
firebase.database().ref('/events').child(eventId).once('value').then((snapshot) => {
let data = snapshot.val();
let items = Object.values(data);
allEventsList.push(items);
this.setState({
allEventsList: allEventsList
});
ToastAndroid.show("kk>" + allEventsList.length, ToastAndroid.SHORT);
}).then((data) => {
}).catch((error) => {
//error callback
console.log('error ', error)
})
}
I'm making an iOS app and I have this problem now.
I'd like to count the number of unread messages in database and assign it in a database different closure. Like below.
exports.arrivalNotifications = functions.database.ref('/trips/{tripId}')
.onCreate((snap, context) => {
const data = snap.val();
const uid = data.uid;
var counter = 0
admin.database().ref('/messages/').on('value', function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var childData = childSnapshot.val();
if (childData.read === false) {
counter += 1
}
});
})
return admin.database().ref('/users/' + uid).once('value', snapshot => {
const data = snapshot.val();
const username = data.username
var payload = {
notification: {
title: username ' has ' + counter + " unread message.",
body: 'Press for more'
}
}
admin.messaging().sendToDevice(toUser.fcmToken, payload)
.then(function(response) {
console.log("Successfully sent message:", response);
return null;
})
.catch(function(error) {
console.log("Error sending message:", error);
});
})
})
So I want to use the counter in the payload but I can't find the way to do it. I'm not familiar with JavaScript so if someone can help me I'd appreciate.
I would write your Cloud Function as follow. Please note that I could not test it and it may need some fine-tuning/debugging... especially since it implies chaining several promises.
exports.arrivalNotifications = functions.database.ref('/trips/{tripId}').onCreate((snap, context) => {
const data = snap.val();
const uid = data.uid;
let counter = 0;
return admin.database().ref('/messages/').once('value')
.then(snapshot => {
snapshot.forEach(function (childSnapshot) {
const childData = childSnapshot.val();
if (childData.read === false) {
counter += 1;
}
});
return admin.database().ref('/users/' + uid).once('value');
})
.then(snapshot => {
const data = snapshot.val();
const username = data.username;
const payload = {
notification: {
title: username + ' has ' + counter + ' unread message.',
body: 'Press for more'
}
};
return admin.messaging().sendToDevice(toUser.fcmToken, payload);
})
.then(response => {
console.log("Successfully sent message:", response);
return null;
})
.catch(error => {
console.log("Error sending message:", error);
});
});
I have an error from firebase while running a cloud function :
FIREBASE WARNING: Exception was thrown by user callback. TypeError:
Cannot convert undefined or null to object
Here is a snippet where the error probably occurs :
// const functions = require('firebase-functions');
// const admin = require('firebase-admin');
// const underscore = require('underscore');
// admin.initializeApp(functions.config().firebase);
// export updateSimilars = functions.database.ref('...').onWrite(event => {
...
for (var i in callerFlattenLikesDislikes) {
getOtherUsersPromises.push(getOtherUsersFromName(callerFlattenLikesDislikes[i], genre));
}
console.log('getOtherUsersPromises length: ' + getOtherUsersPromises.length);
return Promise.all(getOtherUsersPromises).then(dataArr => {
console.log(dataArr); // will never fire
dataArr.forEach(data => {
data.forEach(user => {
if (otherUsers.indexOf(user) > -1 && user !== userId) {
otherUsers.push(user);
}
});
});
....
....
function getOtherUsersFromName(name, genre) {
console.log('fired getOtherUsersFromName: ' + name);
return new Promise((resolve, reject) => {
admin
.database()
.ref('/names/' + genre + '/' + name)
.once('value', snapshot => {
var dic = snapshot.val();
var dislikingUsers = Object.keys(dic['dislikingUsers']);
var likingUsers = Object.keys(dic['likingUsers']);
var users = underscore.union(dislikingUsers, likingUsers);
console.log('will resolve: ' + users);
resolve(users);
});
});
}
Basically, I have an array of promises to be executed asynchronously (the same firebase query for several input items).
I want to gather all the results before starting to process them.
But the .then after Promise.all seems to never be fired, and I have the following firebase logs:
Anyone to help me ?
Thanks !
I think you need to check a name exist or not at the path '/names/' + genre + '/' + name. It gives an error when this path is empty.
function getOtherUsersFromName(name, genre) {
console.log('fired getOtherUsersFromName: ' + name);
return new Promise((resolve, reject) => {
admin
.database()
.ref('/names/' + genre + '/' + name)
.once('value', snapshot => {
if (snapshot.exists()){
var dic = snapshot.val();
var dislikingUsers = Object.keys(dic['dislikingUsers']);
var likingUsers = Object.keys(dic['likingUsers']);
var users = underscore.union(dislikingUsers, likingUsers);
console.log('will resolve: ' + users);
resolve(users);
} else {
// Do something as the path is empty
}
});
});
}