doc is not a function error on deleting document in firebase - javascript

TypeError: doc is not a function
i am using the firebase documentation delete document code
deleteDoc(doc(db,"cafe",id))
bt here it is showing paused due to exception in browser
// Import the functions you need from the SDKs you need
import { initializeApp } from 'https://www.gstatic.com/firebasejs/9.14.0/firebase-app.js';
import { getFirestore,doc, collection, getDocs,addDoc,deleteDoc } from 'https://www.gstatic.com/firebasejs/9.14.0/firebase-firestore.js'
const firebaseConfig = {
apiKey: "AIzaSyC_qbiPqjPCoK4yQ2lzjeinQhx7Co1mEbE",
authDomain: "cafe-review-804eb.firebaseapp.com",
databaseURL: "https://cafe-review-804eb-default-rtdb.asia-southeast1.firebasedatabase.app",
projectId: "cafe-review-804eb",
storageBucket: "cafe-review-804eb.appspot.com",
messagingSenderId: "933248008537",
appId: "1:933248008537:web:a15fe6338d071f2a3c0c48",
measurementId: "G-2JX7DVQTM2"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const db = getFirestore(app)
const cafeList = document.querySelector("#cafe-list")
const form = document.querySelector("#add-cafe-form")
function renderCafe(doc){
let li = document.createElement('li')
let name = document.createElement('span')
let city = document.createElement('span')
let cross = document.createElement('div')
li.setAttribute('data-id',doc.id)
name.textContent = doc.data().name
city.textContent = doc.data().city
cross.textContent = 'x'
li.appendChild(name)
li.appendChild(city)
li.appendChild(cross)
cafeList.appendChild(li)
//delete data
cross.addEventListener('click', (e) => {
e.stopPropagation()
let id = e.target.parentElement.getAttribute('data-id')
console.log(id)
deleteDoc(doc(db,"cafe",id))
})
}
const querySnapshot = await getDocs(collection(db, "cafe"));
querySnapshot.forEach((doc) => {
renderCafe(doc)
});
// save form
form.addEventListener('submit', (e)=> {
e.preventDefault()
const docRef = addDoc(collection(db,"cafe"),{
name: form.name.value,
city: form.city.value
})
form.name.value = ""
form.city.value = ""
})

The problem is that you have two definitions of doc inside your renderCafe function:
The doc you imported from the Firestore SDK with import { ... doc, ... } from.
The doc parameter you pass to renderCafe in function renderCafe(doc){.
Since the parameter is closer in scope than the import, inside your renderCafe function doc refers to the parameter and not the function you imported.
To solve this problem, give the parameter a different name like ``:
function renderCafe(dbdoc){
let li = document.createElement('li')
let name = document.createElement('span')
let city = document.createElement('span')
let cross = document.createElement('div')
li.setAttribute('data-id',dbdoc.id)
name.textContent = dbdoc.data().name
city.textContent = dbdoc.data().city
cross.textContent = 'x'
li.appendChild(name)
li.appendChild(city)
li.appendChild(cross)
cafeList.appendChild(li)
//delete data
cross.addEventListener('click', (e) => {
e.stopPropagation()
let id = e.target.parentElement.getAttribute('data-id')
console.log(id)
deleteDoc(doc(db,"cafe",id))
})
}

Related

Firebase realtime database record only one child

for a specific use, I would like to save in the realtime database only one element and that it is updated when it is modified, I do not need to save all the changes as child.
I have this code but it creates child.
<script type="module">
import {initializeApp} from "https://www.gstatic.com/firebasejs/9.6.6/firebase-app.js";
import {
getDatabase,
set,
ref,
push,
child,
onValue,
onChildAdded
} from "https://www.gstatic.com/firebasejs/9.6.6/firebase-database.js";
const firebaseConfig = {
apiKey: "...",
authDomain: "....firebaseapp.com",
databaseURL: "....firebaseio.com",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "..."
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const database = getDatabase(app);
submit.addEventListener('click', (e) => {
var message = document.getElementById('message').value;
//var name = myName;
const id = push(child(ref(database), 'messages')).key;
set(ref(database, 'messages/' + id), {
//name: name,
message: message
});
document.getElementById('message').value = "";
//alert('message has sent');
});
const dbRef = ref(getDatabase());
const newMsg = ref(database, 'messages/');
onChildAdded(newMsg, (data) => {
var divData = data.val().message;
let h1 = document.querySelector("h1");
h1.textContent = divData;
});
Thanks.
If you don't want to create a child node, you can simply write messages with:
set(ref(database, 'messages'), {
message: message
});

Firebase database doesn't return data

I am currently trying to make an account page for users using data from Firebase auth, database, and storage. The only problem with the code is that the text and images that need data from the database(username and profile picture) are appearing as undefined so it seems like the database isn't returning data
the code:
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.13.0/firebase-app.js"
import { getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword, signOut, onAuthStateChanged } from 'https://www.gstatic.com/firebasejs/9.13.0/firebase-auth.js';
import { getDatabase, set, ref } from 'https://www.gstatic.com/firebasejs/9.13.0/firebase-database.js';
import { getStorage, ref as storageRef, getDownloadURL } from 'https://www.gstatic.com/firebasejs/9.13.0/firebase-storage.js'
const firebaseConfig = {
apiKey: "",
authDomain: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: ""
};
//Initiate firebase services
const app = initializeApp(firebaseConfig);
const auth = getAuth(app)
const database = getDatabase(app)
const storage = getStorage(app)
//Get image folder from storage
const imageFolder = storageRef(storage, "gs://betterbadgeworld.appspot.com/profile-pictures")
//Get user UID and accountData
let user = onAuthStateChanged(auth, (user)=>{
if (user) {
var user = auth.currentUser
return user
}
else {
return
}
})
let accountData = onAuthStateChanged(auth, (user)=>{
if (user) {
var userUID = user.uid
var accountData = ref(database, 'users/' + user.uid)
console.log(accountData)
return accountData
}
else {
return
}
})
//Add username and profile picture to website with accountData
function initializeData(accountData) {
//Get profile picture file name
let userProfilePicture = accountData.profilePicture + ".png"
//Set username in text box
const usernameText = document.createTextNode(accountData.username)
const usernameBox = document.getElementById('username')
usernameBox.appendChild(usernameText)
//Get profile picture div, make gs:// link, and get downloadURL for it
const profilePicBox = document.getElementById("profile-picture")
var profileGSLink = imageFolder + "/" + userProfilePicture
var profileLink = getDownloadURL(storageRef(storage, profileGSLink))
//Make image element and use profileLink as source
let img = document.createElement("img");
img.src = profileLink;
profilePicBox.appendChild(img);
}
initializeData(accountData)
the code that isn't returning the data:
let accountData = onAuthStateChanged(auth, (user)=>{
if (user) {
var accountData = ref(database, 'users/' + user.uid)
console.log(accountData)
return accountData
}
else {
return
}
})

Is there a way to give unique id numbers to a page?

I get the data of all the movies on my home page. But I don't want to do this on the Admin.html page. On the admin page, when I click on the name of the movie, I want to go to the page related to that movie. For example, when I click on the movie "Schindler's List" which movieId is 3 (Admin.html?movieId=3), I want to go to a page with only Schindler's List movie information. It will show only Schindler List's img,score,name. How can I achieve this?
Admin.html
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.4.0/firebase-app.js";
import { getDatabase, set, ref, update, get, child } from "https://www.gstatic.com/firebasejs/9.4.0/firebase-database.js";
import { getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword, onAuthStateChanged, signOut } from "https://www.gstatic.com/firebasejs/9.4.0/firebase-auth.js";
const firebaseConfig = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: ""
};
const app = initializeApp(firebaseConfig);
const db = getDatabase(app);
const auth = getAuth(app);
btnCreate.addEventListener('click',(e)=>{
var movieId = document.getElementById('movieId').value;
var movieName = document.getElementById('movieName').value;
var movieScore = document.getElementById('movieScore').value;
var movieImage = document.getElementById('movieImage').value;
set(ref(db, 'Movies/' + movieId), {
movieId: movieId,
movieName: movieName,
movieScore: movieScore,
movieImage : movieImage
});
});
let html = '';
var body = document.getElementById('editor');
var body2 = document.getElementById('week');
function AddItemsToTable(name,score,img,id){
let html='';
const movies=`
<div class="content"><img src="${img}"><p>${name}</p> <p> <img src="img/mutlu.png" class="emoji"><a class="scoretxt">${score}</a> </p> </div>
`;
html = movies;
body.innerHTML += html;
body2.innerHTML+=html;
}
function AddAllItemsToTable(TheMovies){
body.innerHTML="";
TheMovies.forEach(element => {
AddItemsToTable(element.movieName, element.movieScore, element.movieImage,element.movieId);
});
}
function getAllDataOnce(){
const dbRef=ref(db);
get(child(dbRef,"Movies"))
.then((snapshot)=>{
var movies=[];
snapshot.forEach(childSnapshot => {
movies.push(childSnapshot.val())
});
AddAllItemsToTable(movies);
});
}
window.onload= getAllDataOnce;

Firebase || read data from database

Below is the older version to read data from firestore
db.collection('cafes').get().then(snapshot => {
snapshot.docs.forEach(doc => {
console.log(docs)
});
});
I think that's why I am getting db.collection() is not a function.
But from the present docs, it is like
async function getcafes(db) {
const cafesCol = collection(db, 'cafes');
const cafeSnapshot = await getDocs(cafesCol);
const cafeList = cafeSnapshot.docs.map(doc => doc.data());
console.log(cafeList)
return cafeList;
}
So while using console.log(), it is not giving any output.
<head>
<script type="module">
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.6.1/firebase-app.js";
import {
getFirestore,
collection,
getDocs,
} from "https://www.gstatic.com/firebasejs/9.6.1/firebase-firestore.js";
const firebaseConfig = {
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
const analytics = getAnalytics(app);
window.db = db; // to make db global variable
async function getcafes(db) {
console.log('Fetching Cafes');
const cafesCol = collection(db, "cafes");
const cafeSnapshot = await getDocs(cafesCol);
const cafeList = cafeSnapshot.docs.map((doc) => doc.data());
console.log(cafeList);
return cafeList;
}
getcafes() // calling the function
</script>
The issue is that within getcafes(), db is undefined, as db within the function is a local parameter. Try removing the db parameter from getcafes and allowing it to use the global window.db.
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
const analytics = getAnalytics(app);
window.db = db; // to make db global variable
// remove db parameter VV
async function getcafes() {
console.log("Fetching Cafes");
// now db here is the global database instead of undefined
const cafesCol = collection(db, "cafes");
const cafeSnapshot = await getDocs(cafesCol);
const cafeList = cafeSnapshot.docs.map((doc) => doc.data());
console.log(cafeList);
return cafeList;
}
getcafes(); // calling the function

Firebase auto deleting function deleting element in secs when asked to delete after 2 hours

I couldn't figure what am I doing wrong so need an extra eye to figure out what am I doing wrong.
I am trying out one the question's answer from Delete firebase data older than 2 hours which uses https://github.com/firebase/functions-samples/tree/master/delete-old-child-nodes and https://github.com/firebase/functions-samples/blob/master/delete-old-child-nodes/functions/index.js to delete a node after a time.
/root
/items
LoHgJSFt8hHi2o_hP: {
timestamp: 1497911193083,
...some_other_data
},
LoHgJSsGGHi2o_fD: {
timestamp: 1597911193083
...some_other_data
}
My index.js looks like
//index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const { createUser } = require('./auth/onCreate');
const { deleteOldData } = require('./auth/onDeleteOldData');
const serviceAccount = require('./ownerstown-admin.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://ownexxxxxxxx-c86cf.firebaseio.com'
});
exports.createUser = functions.firestore.document('users/{userId}').onCreate(createUser);
exports.deleteOldData = functions.database.ref('/referralIds/ids/{pushId}').onWrite(deleteOldData);
and then onDeleteOldData.js
// auth/onDeleteOldData.js
const CUT_OFF_TIME = 2 * 60 * 60 * 1000;
async function deleteOldData(change) {
console.log('starting nooowwwwwww');
const ref = change.after.ref.parent;
console.log('ref', ref);
const now = Date.now();
const cutoff = now - CUT_OFF_TIME;
const oldItemsQuery = ref.orderByChild('timestamp').endAt(cutoff);
const snapshot = await oldItemsQuery.once('value');
console.log('snapshot', snapshot);
const updates = {};
snapshot.forEach(child => {
updates[child.key] = null;
});
return ref.update(updates);
}
module.exports = {
deleteOldData
};
and pushing the data in a button click like
function createLoginId() {
const rootRef = Firebase.database.ref();
const allDetails = rootRef.child('referralIds/ids');
const timeStamp = Date.now();
const someId = uuidv4();
const { origin } = window.location;
const data = {
timeStamp,
someId,
createrId: id
};
const newRef = allDetails.push();
newRef.set(data);
}
But as soon as I push the data, it gets deleted in secs.
What am doing wrong?
The problem comes from the fact that when you write to the database you do
const timeStamp = Date.now();
//...
const data = {
timeStamp,
someId,
createrId: id
};
which means that you save a field timeStamp, but your Cloud Function selects the node(s) to be deleted based on timestamp (all in lower case).
Node names in the Realtime Database are case sensitive.
BTW, note that for the timestamp you could use
const timestamp = firebase.database.ServerValue.TIMESTAMP;
which is "a placeholder value for auto-populating the current timestamp as determined by the Firebase servers", see https://firebase.google.com/docs/reference/js/firebase.database.ServerValue

Categories

Resources