Vue, firebase database return the empty array - javascript

I am trying to retrieve the data from firebase database.
And I can connect to firebase auth and check currentUser data, it's fine.
But I can't retrieve the data from firebase database, it just return the empty array.
firebase version = 5.0.4
vue version = 2.5.16
The database structure
users/
--------uId/
--------------name
--------------email
Vue Js folder structure
App.vue
firebase.js
main.js
components /
------------ Home.vue
firebase.js
var firebase = require('firebase');
require("firebase/auth");
require("firebase/database");
var config = {
apiKey: "...",
authDomain: "...",
databaseURL: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "..."
};
firebase.initializeApp(config)
export const auth = firebase.auth();
export const db = firebase.database()
Home.vue
<script>
import {db} from './../firebase';
import {auth} from './../firebase';
var usersRef = db.ref('users');
export default {
name: "Home",
components: {
add_new
},
data(){
return {}
},
mounted: function(){
console.log(usersRef);
var userId = auth.currentUser.uid;
return db.ref('/users/' + userId).once('value').then(function(snapshot) {
snapshot.forEach(function (childData) {
console.log(childData.val())
})
})
}
}
</script>
Here, Vue app works correctly,
only the firebase.database ( usersRef ) returns the empty array.
This is the screenshot of console.log(usersRef) result
https://i.stack.imgur.com/NH7gh.png

First instead of using multiple import statements, why not
import {auth, db} from './../firebase';
And try to change
snapshot.forEach(function (childData) {
console.log(childData.val())
})
to snapshot.val()
var userId = auth.currentUser.uid;
return db.ref('/users/' + userId).once('value').then(function(snapshot) {
console.log(snapshot.val());
});

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;

Vue.js Cannot read property 'collection' of undefined

I'm using Vue.js and firestore to make a landing page for my project, I've tried to make a registration form to make new account for my website.
I've created a collection in my firebase project, named "users", where the user information where stored when the sign up completed. But when I call the function, the error appeared:
Cannot read property 'collection' of undefined
What can I do? I'll share my code here:
Signup.vue
import { Auth, db, usersCollection } from '#/firebase/auth.js'
import * as fb from 'firebase'
import {App} from '#/firebase/app.js'
async addEmail(email,password) {
var noticeMessage = "🎉 Your account has been reserved 🎉"
const {user} = await Auth.createUserWithEmailAndPassword(email, password )
await fb.usersCollection.doc(user.uid).set({
email: email,
password: password,
userId: user.uid,
createdAt: new Date().toISOString(),
})
auth.js
import {App} from './app';
import 'firebase/auth';
import 'firebase/firestore';
import 'firebase/storage';
var config = {
apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
authDomain: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
databaseURL: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
projectId: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
storageBucket: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
messagingSenderId: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
appId: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
measurementId: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
export const Auth = App.auth();
export const db = App.firestore();
export const usersCollection = db.collection('users')
app.js
import Firebase from 'firebase/app'
import credentials from './credentials'
export const App = Firebase.initializeApp(credentials.config);
async-firestore.js
import firebase from 'firebase/app'
import { isNil } from 'lodash'
let asyncFirestore = null
// Lazy load firestore with async import is important for performance
export default () => {
if (isNil(asyncFirestore)) {
asyncFirestore = import(/* webpackChunkName: "chunk-firestore" */ 'firebase/firestore').then(
() => {
firebase.firestore().settings({})
firebase.firestore().enablePersistence({ synchronizeTabs: true })
return firebase.firestore()
}
)
}
return asyncFirestore
}
generic-db.js
import { isNil, keys, cloneDeep } from 'lodash'
import firebase from 'firebase/app'
import firestore from './async-firestore'
export default class GenericDB {
constructor(collectionPath) {
this.collectionPath = collectionPath
}
/**
* Create a document in the collection
* #param data
* #param id
*/
async create(data, id = null) {
const collectionRef = (await firestore()).collection(this.collectionPath)
const serverTimestamp = firebase.firestore.FieldValue.serverTimestamp()
const dataToCreate = {
...data,
createTimestamp: serverTimestamp,
updateTimestamp: serverTimestamp
}
const createPromise = isNil(id)
? // Create doc with generated id
collectionRef.add(dataToCreate).then(doc => doc.id)
: // Create doc with custom id
collectionRef
.doc(id)
.set(dataToCreate)
.then(() => id)
const docId = await createPromise
return {
id: docId,
...data,
createTimestamp: new Date(),
updateTimestamp: new Date()
}
}
/**
* Read a document in the collection
* #param id
*/
async read(id) {
const result = await (await firestore())
.collection(this.collectionPath)
.doc(id)
.get()
const data = result.exists ? result.data() : null
if (isNil(data)) return null
this.convertObjectTimestampPropertiesToDate(data)
return { id, ...data }
}
/**
* Read all documents in the collection following constraints
* #param constraints
*/
async readAll(constraints = null) {
const collectionRef = (await firestore()).collection(this.collectionPath)
let query = collectionRef
if (constraints) {
constraints.forEach(constraint => {
query = query.where(...constraint)
})
}
const formatResult = result =>
result.docs.map(ref =>
this.convertObjectTimestampPropertiesToDate({
id: ref.id,
...ref.data()
})
)
return query.get().then(formatResult)
}
/**
* Update a document in the collection
* #param data
*/
async update(data) {
const { id } = data
const clonedData = cloneDeep(data)
delete clonedData.id
await (await firestore())
.collection(this.collectionPath)
.doc(id)
.update({
...clonedData,
updateTimestamp: firebase.firestore.FieldValue.serverTimestamp()
})
return id
}
/**
* Delete a document in the collection
* #param id
*/
async delete(id) {
return (await firestore())
.collection(this.collectionPath)
.doc(id)
.delete()
}
/**
* Convert all object Timestamp properties to date
* #param obj
*/
convertObjectTimestampPropertiesToDate(obj) {
const newObj = {}
keys(obj)
.filter(prop => obj[prop] instanceof Object)
.forEach(prop => {
if (obj[prop] instanceof firebase.firestore.Timestamp) {
newObj[prop] = obj[prop].toDate()
} else {
this.convertObjectTimestampPropertiesToDate(obj[prop])
}
})
return {
...obj,
...newObj
}
}
}
init.js
import firebase from 'firebase/app'
import 'firebase/auth'
const config = {
apiKey: ...,
authDomain: ...,
databaseURL: ...,
projectId: ...,
storageBucket: ...,
messagingSenderId: ...,
appId: ...,
}
firebase.initializeApp(config)
users-db.js
import GenericDB from './generic-db'
export default class UsersDB extends GenericDB {
constructor() {
super('users')
}
}
main.js
...
// firebase setup
import './firebase/init'
...
You can do firebase auth like this
import firebase from 'firebase/app'
...
const { user } = await firebase
.auth()
.createUserWithEmailAndPassword(form.email, form.password)
// create a user in firestore `users` table
const userDb = new UsersDB()
const newUser = {
email: form.email,
name: form.name,
}
userDb.create(newUser, user.uid)
...

firebase.database() is not a function

Error message:
TypeError: _this.db is not a function
Code:
import app from "firebase/app";
import "firebase/auth";
import "firebase/database";
const config = {
apiKey: "some-api-key",
authDomain: "myapp.firebaseapp.com",
databaseURL: "https://myapp.firebaseio.com",
projectId: "aofndiuf",
storageBucket: "project-somenumber.appspot.com",
messagingSenderId: "793813245724y6597"
};
class Firebase {
constructor() {
app.initializeApp(config);
this.auth = app.auth();
this.db = app.database();
}
// Auth API
doCreateNewsletter = (news, name, description, email) => {
const newsletter = { news, name, description, email };
const newPostKey = this.db()
.ref()
.child("newsletters")
.push().key;
return this.db
.ref()
.child("/newsletters/" + newPostKey)
.set(newsletter);
};
You assigned this.db like this:
this.db = app.database();
But then you refer to it later like this:
const newPostKey = this.db()
...
The object returned from app.database() isn't a function, so you can't call it like a function as you are now. It's a Database object. Perhaps you can just get rid of those parenthesis to make your code work the way you intended.

Categories

Resources