Vue and Firebase RTDB connection - javascript

I have followed few different tutorials, read numerous posts on SO, but still my firebase RTDB won't connect. It doesnt even throw any error.
At this point my file in db/database.js looks like this (I stripped it from connection data):
const firebaseConfig = {
apiKey: "key",
authDomain: "",
databaseURL: "https://database_name.europe-west1.firebasedatabase.app",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: ""
};
firebase.initializeApp(firebaseConfig);
const firebaseDb = firebase.database()
export default firebaseDb
the method that I use to call the database ref in store/index.js
dbReadSettings() {
console.log("I'm here");
let settings = firebaseDb.ref('userSettings/', function(error) { console.log(error) });
settings.on('value', (snapshot) => {
const data = snapshot.val();
console.log(data)
}, function(error) {
console.log(error) })
}
The result is none – the console logs out I'm here" and then nothing else (I tried many different ways). I checked the path and the documentation but it does not connect at all. Any help?

the ref method only receives one parameter.
dbReadSettings() {
console.log("I'm here");
let settings = firebaseDb.ref('userSettings/');
settings.on('value', (snapshot) => {
const data = snapshot.val();
console.log(data)
}, (error) => {
console.log(error)
})
}

That first callback you have is not needed, and will in fact never be called. Since you attach the listener inside that callback, the listener will never be attached.
You can easily check this by adding an extra log line:
console.log("I'm here");
let settings = firebaseDb.ref('userSettings/', function(error) { console.log(error) });
console.log("Now I'm here");
settings.on('value', (snapshot) => {
const data = snapshot.val();
console.log(data)
}, function(error) {
console.log(error);
});
})
While you'll see:
I'm here
You'll never see:
Now I'm here
To fix this, remove the extraneous callback and just attach the listener right after you create the reference (which is not an asynchronous operation):
console.log("I'm here");
let settings = firebaseDb.ref('userSettings/')console.log(error) });
settings.on('value', (snapshot) => {
const data = snapshot.val();
console.log(data)
}, function(error) {
console.log(error);
});

Related

How to log out from both server side and client side on a SSR Nuxt.js application using Firebase authentication?

As the title suggests, in my Nuxt webapp using Firebase auth in SSR mode, I want to have the following behaviour :
As a client, by clicking on logout button from my profile space, I want to keep this state even if I reload the page.
But for the moment it seems to be that I'm only log-out from the client side (by clearing cookies, vuex store) but on server side User data/session looks still alive, then on page refresh with F5 the vuex store is set-up again, even if we add 'gates' to prevent it ! (check cookies from req object, get local user from res object).
I think something is missing in my config, so can someone tell me what is it ?
=> Here the nuxt.config.js file :
// ...
firebase: {
config: {
apiKey: process.env.FIREBASE_API_KEY,
authDomain: `${process.env.FIREBASE_PROJECT_ID}.firebaseapp.com`,
databaseURL: process.env.FIREBASE_DATABASE_URL,
projectId: process.env.FIREBASE_PROJECT_ID,
storageBucket: `${process.env.FIREBASE_PROJECT_ID}.appspot.com`,
messagingSenderId: process.env.FIREBASE_SENDER_ID,
appId: process.env.FIREBASE_APP_ID,
},
services: {
auth:
{
ssr: true
},
firestore: true
}
},
// ...
pwa: {
manifest: {
// ...
},
workbox: {
importScripts: ['firebase-auth-sw.js'],
dev: process.env.ENV === 'development', // Must be FALSE for prod env.
},
},
// ...
=> The index.js store :
import { vuexfireMutations } from 'vuexfire';
import cookieparser from 'cookieparser';
export const mutations = {
// Plugin used for Firestore operations (read, write)
...vuexfireMutations,
};
export const actions = {
async nuxtServerInit({ dispatch }, { req, res }) {
if (process.server && process.static) return;
if (!req?.headers?.cookie) return;
const { token: currToken } = cookieparser.parse(req.headers.cookie);
if (!currToken) return;
if (!res?.locals?.user) return;
const { allClaims: claims, idToken: token, ...authUser } = res.locals.user
console.info('Auth User verified on server-side. User: ', authUser, 'Claims:', claims)
dispatch('onAuthStateChanged', { authUser, claims, token })
},
onAuthStateChanged({ commit }, { authUser, claims, token }) {
console.log('authUser :', authUser);
if (!authUser) {
commit('user/resetState');
return;
}
// Set existing user into vuex store
const existingUser = {
uid: authUser.uid,
email: authUser.email,
token: token,
}
commit('user/setUser', existingUser);
},
};
=> The log-out method from store/user.js :
async logOut({ commit }) {
try {
await this.$fire.auth.signOut();
commit('resetState');
this.$cookies.removeAll()
} catch (error) {
console.error('Error on logout process from client side :', error);
throw error;
}
},
To be more precise, on page refresh, the user data is set again without calling the commit('user/setUser', existingUser); line ! Don't know how and why...
Thanks in advance for any help ! :)

Firebase db with vuejs : default.collection is not a function

I'm starting a small project with Vuejs and Firebase. I am trying to upload Name and Price to Firestore. I checked their documentation and few tutorials, but I am stuck with this error.
<div class="form-group">
<v-btn v-on:click="saveData" class="btn btn-primary">Save data</v-btn>
</div>
import db from "../firebase";
export default {
name: "products",
props: {
msg: String,
},
data() {
return {
aon: {
Name: null,
Price: null,
},
};
},
methods: {
saveData() {
db.collection("Products")
.add(this.Product)
.then((docRef) => {
console.log("Document written with ID: ", docRef.id);
})
.catch((error) => {
console.error("Error adding document: ", error);
});
},
},
};
Here is my firebase.js
import firebase from '#firebase/app';
import '#firebase/auth';
import '#firebase/firestore';
const fb = firebase.initializeApp({
apiKey: "!!!!!!!!!!!",
authDomain: "!!!!!!!!",
databaseURL: "!!!!!!!",
projectId: "!!!!!!",
storageBucket: "!!!!!!!",
messagingSenderId: "!!!!!!!",
appId: "!!!!!!!!!",
measurementId: "!!!!!!!!!!!!"
});
const db = firebase.firestore();
export default firebase;
export {db,fb} ;
First you didn't initialized your firebase app. To do so :
//firebase.js
const db = firebase.initializeApp(fb)
export {db.firestore(),fb}
Then on your products page or component you wrote :
//products.vue
db.collection("Products").add(this.Product)...
this.Product object doesn't exist so it should be this.aon
//products.vue
db.collection("Products").add(this.aon)...
For more info : https://firebase.google.com/docs/firestore/quickstart
As per the documentation here and here you need to use the .set(), .add(), .update() and .doc() methods like this.
When you use set() to create a document, you must specify an ID for the document to create. For example:
await db.collection('cities').doc('new-city-id').set(data);
to let Cloud Firestore auto-generate an ID for you. You can do this by calling add()
// Add a new document with a generated id.
const res = await db.collection('cities').add({
name: 'Tokyo',
country: 'Japan'
});
console.log('Added document with ID: ', res.id);
In some cases, it can be useful to create a document reference with an auto-generated ID, then use the reference later. For this use case, you can call doc()
const newCityRef = db.collection('cities').doc();
// Later...
const res = await newCityRef.set({
// ...
});
To update some fields of a document without overwriting the entire document, use the update() method:
const cityRef = db.collection('cities').doc('DC');
// Set the 'capital' field of the city
const res = await cityRef.update({capital: true});

Bot Framework v4 - initiate chat with a user ( proactive messages )

I would like to start a conversation with a user without that he already chatted with the bot.
I'm proceeding bu getting the conversationId when user install the bot app as mentionned here
Here how I catch reference and serviceUrl by using processActivity event
Then I use continueConversation + reference
const {
BotFrameworkAdapter,
} = require('botbuilder');
const adapter = new BotFrameworkAdapter({
appId: "xxxx",
appPassword: "xxxxy"
})
module.exports = async function(context, req) {
console.log(adapter);
try {
adapter.processActivity(req, context.res, async (turnContext) => {
const reference = turnContext.activity.conversation.id
const serviceUrl = turnContext.activity.serviceUrl
await adapter.continueConversation(reference, async (turnContext) => {
try {
await turnContext.sendActivity("this is proacive message");
} catch (e) {
console.log(e)
}
});
});
} catch (e) {
console.log(e)
}
return;
};
I'm getting this error
Error: BotFrameworkAdapter.sendActivity(): missing serviceUrl.
I have checked the turnContext.activity values. I get :
{"type":"event","name":"continueConversation"}" all other values are undefined ( serviceUrl also )
I noticed that turnContext.activityinside adapter.processActivity is not the same as in adapter.continueConversation and have all the serviceUrl and conversationId
How can I edit this code example to be able to send proactive messages to users?
The const reference needs to be ConversationReference not just the Id if you are using it for BotFrameworkAdapter.continueConversation().
A ConversationReference can be retrieved by using:
const reference = TurnContext.getConversationReference(turnContext.activity);
https://learn.microsoft.com/en-us/javascript/api/botbuilder/botframeworkadapter?view=botbuilder-ts-latest#continueconversation-partial-conversationreference----context--turncontext-----promise-void--
https://learn.microsoft.com/en-us/javascript/api/botbuilder-core/turncontext?view=botbuilder-ts-latest#getconversationreference-partial-activity--

No error but not writing into firestore. The code works in 7.9.1 but this is 7.14.1. Is this the error?

I am trying to write into Firestore using Javascript but it doesn't work although there is no error. I am using 7.14.1 version. This code ran properly on 7.9.1 so I don't know if this is the error.
<script src="https://www.gstatic.com/firebasejs/7.14.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.1/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.1/firebase-auth.js"></script>
<!-- TODO: Add SDKs for Firebase products that you want to use
https://firebase.google.com/docs/web/setup#available-libraries -->
<script src="https://www.gstatic.com/firebasejs/7.14.1/firebase-analytics.js"></script>
I try to console log before reading data, it works but the console log after reading data does not work.
function retriveid(){
fireauth.onAuthStateChanged(function(user) {
if (user) {
var user = fireauth.currentUser;
if (user != null) {
user.providerData.forEach(function () {
console.log("Firestore loaded");
const songname = document.getElementById('songname');
const singername = document.getElementById('singer');
const youtubelink = document.getElementById('ytlink');
const audiolink = document.getElementById('aulink')
console.log(categoryname.value, songname.value, singername.value, youtubelink.value, audiolink.value, user.uid);
firestore.collection("song").doc("Rock").set({
song_name: songname.value,
singer_name: singername.value,
youtube_link: youtubelink.value,
audio_link: audiolink.value
})
.then(function(){
console.log("Document successfully written!");
})
.catch(function(error){
console.error("Error writing document: ", error);
})
});
}
} else {
// No user is signed in.
console.log("not yet log in")
}
});
}
Hi Doug i have the same error, only you need modify the link in "...firebase-app.js" to "...firebase.js"
<script src="https://www.gstatic.com/firebasejs/7.14.1/firebase.js"></script>
the function ..listAll() works correctly. It will help you a lot, I had to consult several sources, i leave you an example:
storageRef = firebase.storage().ref('images/'+idReport);
storageRef.listAll().then(function(result) {
result.items.forEach(function(imageRef) {
// And finally display them
displayImage(imageRef);
});
}).catch(function(error) {
// Handle any errors
});
function displayImage(imageRef) {
imageRef.getDownloadURL().then(function(url) {
console.log("url", url);
}).catch(function(error) {
console.log("error", error);
});
}

TypeError: this.path.replace is not a function at new FirestoreDelete

Trying to remove the users`s data calling a function from app.
'use strict';
const functions = require('firebase-functions');
const firebase_tools = require('firebase-tools');
const admin = require('firebase-admin');
const serviceAccount = require('./myapp.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://myapp.firebaseio.com"
});
let db = admin.firestore();
exports.mintAdminToken = functions.https.onCall((data, context) => {
const uid = data.uid;
return admin
.auth()
.createCustomToken(uid, { admin: true })
.then(function(token) {
return { token: token };
});
});
exports.recursiveDelete = functions
.runWith({
timeoutSeconds: 540,
memory: '1GB'
})
.https.onCall((data, context) => {
if (!(context.auth && context.auth.token )) {
throw new functions.https.HttpsError(
'permission-denied',
'Must be an administrative user to initiate delete.'
);
}
let path = data.path;
console.log(
`User ${context.auth.uid} has requested to delete path ${path}`
);
return firebase_tools.firestore
.delete(path, {
project: process.env.GCLOUD_PROJECT,
recursive: true,
yes: true,
token: functions.config().fb.token
})
.then(() => {
return {
path: path
};
});
});
and I pass the path like:
Map<String, Object> data = new HashMap<>();
data.put("path", "./users/rnAjpK4LLSMMlENZqe4l3F2");
result:
Function execution took 540003 ms, finished with status: 'timeout'
probably the problem is in path. if I change for this line:
let path = admin.firestore().doc('users/' + context.auth.uid);
Im getting an error
Unhandled error TypeError: this.path.replace is not a function at new FirestoreDelete
is the problem with "path"?
what will be the right path to delete then?
I use this example https://github.com/firebase/snippets-node/tree/master/firestore/solution-deletes but here is nothing about it
UPDATED:
with
String path = "./users/rnAjpK4LLSMMlENAgrZqe4l3F2";
or
String data = "./users/rnAjpK4LLSMMlENAgrZqe4l3F2";
an error
Unhandled error { FirebaseError: Must specify a path. at Object.reject (/srv/node_modules/firebase-tools/lib/utils.js:82:27)
solution
const id = context.auth.uid;
const path = `users/${id}`;
As far as I can see from reading the code of the delete function, the path you pass in has to be a single string value of the collection or document to delete. The function will then delete all data under that collection or document.
I was accidentally sending an entire object. If you come across this question, double check you're not making the same mistake.

Categories