What next when the user is logged? - javascript

I am trying to integrate google auth from Firebase into my web app (on GAS), and i am having a hard time. I am new to it and have few experience in developing so excuse my lack of precision.
I managed to implement several steps but fail to come back to navigate the app normally once the user has logged.
First, here are the steps that are working fine (at least they seem to):
doGet() returns HtmlService.createHtmlOutputFromFile('auth') which contains all the necessary code for the authentication.
'auth.html' calls necessary stuff from firebase via CDN and the behaviour is correct: if i am not logged: UI shows and if i am logged: user details show on screen.
Since i need the userID to go on with the server-side scripts, i pass the userID which for now is just used to check i have the value on server side (is that correct to use userID this way?);
EDITED QUESTION:
Now what i would like to understand is the best practice for the steps
User opens app
doGet() is run and loads 'auth.html'
client-side authentication runs and collects user data
userID is set as a variable to be passed to server
then in order to run the rest of the scripts (the real app content user needs to see) what is the way to go? Should some function be run through google.script.run.someFunction(userID) when user is logged that would run the 'normal' app content (as it was before i integrated any authentication to be clear)?
last question: Does the authentication needs to be run on every page before loading content?
Here is my code:
.gs
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('auth2')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
.setTitle('FirebaseUI | Firebase Authentication');
}
auth.html
<base target="_top">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://www.gstatic.com/firebasejs/7.14.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.2/firebase-auth.js"></script>
<script src="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.css" />
<script>
var firebaseConfig = {
apiKey: "stackoverflow",
authDomain: "stackoverflow.firebaseapp.com",
databaseURL: "https://stackoverflow-default-rtdb.europe-west1.firebasedatabase.app",
projectId: "stackoverflow",
storageBucket: "stackoverflow.appspot.com",
messagingSenderId: "267227785525",
appId: "1:stackoverflow:web:stackoverflow",
measurementId: "G-stackoverflow"
};
firebase.initializeApp(firebaseConfig);
</script>
<script>
google.script.run.withSuccessHandler(function(url) {
var uiConfig = {
signInFlow: 'redirect',
signInSuccessUrl: url,
signInOptions: [
firebase.auth.GoogleAuthProvider.PROVIDER_ID
],
};
var ui = new firebaseui.auth.AuthUI(firebase.auth());
var user = firebase.auth().currentUser;
console.log(user);
if (user) {
document.getElementById("signOut").style.display = "inline-block";
} else {
ui.start('#firebaseui-auth-container', uiConfig);
}
})
.webAppUrl();
</script>
<script>
initApp = function() {
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
user.getIdToken().then(function(accessToken) {
document.getElementById('account-details').textContent = JSON.stringify({
displayName: user.displayName,
email: user.email,
custom: user.email,
emailVerified: user.emailVerified,
phoneNumber: user.phoneNumber,
photoURL: user.photoURL, // remove quotes to get the photoURL
uid: user.uid,
accessToken: "hidden", // replace "hidden" with accessToken
providerData: user.providerData // remove quotes to get the photoURL
}, null, ' ');
});
const userID = user.email;
google.script.run.someFunction(userID);
} else {
document.getElementById('account-details').textContent = '';
}
});
};
window.addEventListener('load', function() {
initApp();
});
</script>
</head>
Here the documentation i read:
https://developers.google.com/apps-script/guides/html/communication
https://firebase.google.com/docs/auth/web/google-signin

Related

How do I display real-time firebase data on my website?

I am trying to post the data from a moisture sensor on a website. I am using Arduino to update and send the data to a Real-Time Firebase database. From there I am using Glitch.com for my website. I am using a moisture sensor, and have the variable 'Moisture' in my database where the values are stored and updated every 0.3 seconds. I currently have the following code:
HTML File
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/styles.css">
<script src="https://www.gstatic.com/firebasejs/4.11.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.11.0/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.11.0/firebase-database.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.11.0/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.11.0/firebase-storage.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.11.0/firebase-messaging.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "xx",
authDomain: "xx",
databaseURL: "xx",
projectId: "xx",
storageBucket: "xx",
messagingSenderId: "xx",
appId: "xx"
};
firebase.initializeApp(config);
</script>
<script>
var database = firebase.database();
var ref = firebase.database().ref("plant-patrol/Moisture");
ref.once("value")
.then(function(snapshot) {
var key = snapshot.key; // "plant-patrol"
var childKey = snapshot.child("plant-patrol/Moisture").key; // "Moisture"
});
</script>
<script>
var ref = firebase.database().ref("plant-patrol/Moisture");
ref.on("value", function(snapshot) {
console.log(snapshot.val());
}, function (error) {
console.log("Error: " + error.code);
});
</script>
<script src="/script.js" defer></script>
</head>
</html>
JS File
auth.onAuthStateChanged(currentUser => console.log(currentUser));
auth.signInAnonymously();
I have no idea what this JS code does, but I copied it from another question on Stack Overflow.
Now as stated before, the path in the Realtime Firebase db I want to display is 'Moisture', that is also the only data in the db. I have tried messing around a bit with the childkey and snapshot, and tried reading into what they actually do. Sadly I was not able to display any form of data, not even in the console.
The read & write lines in Firebase have both been set to True as security is not relevant (school project). I was also wondering if it is possible to update the data on the website without having to refresh the page.
Update
Made a bit of progress,read my comments below!

Firebase web app: firebase.database is not a function [duplicate]

This question already has answers here:
firebase.database is not a function
(9 answers)
Closed 3 years ago.
I am working on an application for android that lets people login and add their data for an amusement park and I also need an app to view the data stored in the database (such as name, birthdate, children etc) on a PC. I have tried to write a web app but I have a problem connecting it to the database. I am new to databases so it might be from my code, can someone help me? The app only needs to show me the database all the time and update when a person registers.
Currently, I am getting this error:
Uncaught TypeError: firebase.database is not a function
at index.html:33
at index.html:66
Here is my index.html file:
<html>
<head>
<meta charset="utf-8"/>
<script src="https://www.gstatic.com/firebasejs/7.6.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.6.1/firebase-analytics.js"></script>
<title>Freaky Firebase Example</title>
</head>
<body>
<h1>Freaky Firebase Realtime Database Example</h1>
<pre id='object'></pre>
<script>
(function(){
// Initialize Firebase
var firebaseConfig = {
apiKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
authDomain: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX.com",
databaseURL: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX.com",
projectId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
storageBucket: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX.com",
messagingSenderId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
appId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
measurementId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
};
firebase.initializeApp(firebaseConfig);
firebase.analytics();
var userDataRef = firebase.database().ref("UserData").orderByKey();
userDataRef.once("value").then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key;
var childData = childSnapshot.val();
var name_val = childSnapshot.val().Name;
var id_val = childSnapshot.val().AssignedID;
$("#name").append(name_val);
$("#id").append(id_val);
});
});
/* Data Event Listeners Start */
const preObject = document.getElementById('object');
const dbRefObject = firebase.database().ref().child('object');
dbRefObject.on('value', snap => {
console.log(snap.val());
preObject.innerText = JSON.stringify(snap.val(), null, 3);
}, function(error) {
// The fetch failed.
console.error(error);
});
/* Stop */
}());
</script>
</body>
</html>
Along with firebase-app and firebase-analytics, you must import the firebase-database service.
<script src="https://www.gstatic.com/firebasejs/7.6.1/firebase-database.js"></script>

I receive: firebase.database is not a function error when trying to connect my form to the database

I'm trying to connect my contact form to a firebase database and i keep getting the firebase.database is not a function error continuously.
I'm also using parcel-bundler for this project and also getting these errors:
at Object.parcelRequire.firebase.js (firebase.js:44)
at newRequire (firebase.js:44)
at firebase.js:44
at firebase.js:44
I really don't know what I'm doing wrong, after looking at similar problems none of them could provide a solution.
This is how I am linking my files:
<script src="https://www.gstatic.com/firebasejs/6.0.2/firebase-app.js"></script>
<script src="./firebase.js"></script>
<script src="./main.js"></script>
</body>
This is the code from my firebase.js file:
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "AIzaS*************r48uEU",
authDomain: "k********irebaseapp.com",
databaseURL: "https://*******irebaseio.com",
projectId: "k******",
storageBucket: "k**********m",
messagingSenderId: "984****903",
appId: "1:9843179**********3734705af"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
var messageRef = firebase.database().ref("messages");
//grab a form
document.querySelector(".contact-form").addEventListener("submit", submitForm);
function submitForm(e) {
e.preventDefault();
// get values
var name = getInputVal("name");
var email = getInputVal("email");
var number = getInputVal("phone");
var message = getInputVal("message");
saveMessage(name, email, number, message);
}
function getInputVal(id) {
return document.getElementById(id).value;
}
function saveMessage(name, email, number, message) {
var newMessageRef = messageRef.push();
newMessageRef.set({
name: name,
email: email,
number: number,
message: message
});
}
Any help will be deeply appreciated, thanks guys.
You're currently only including this for Firebase:
<script src="https://www.gstatic.com/firebasejs/6.0.2/firebase-app.js"></script>
This only contains the definition of FirebaseApp, and doesn't include Firebase Authentication (firebase.auth()) or Firebase Realtime Database (firebase.database()). To include those, be sure to include the correct scripts for that too:
<script src="https://www.gstatic.com/firebasejs/6.0.2/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/6.0.2/firebase-database.js"></script>

Getting an Error on console while saving data in firebase firestore

here is my Javascript code. its simply copy from the firebase Docs
<script src="https://www.gstatic.com/firebasejs/5.4.2/firebase.js"/></script>
<script src="https://www.gstatic.com/firebasejs/5.3.0/firebase-firestore.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: ".",
authDomain: ".",
databaseURL: ".",
projectId: ".",
storageBucket: ".",
messagingSenderId: ".[enter image description here][1]"
};
firebase.initializeApp(config);
// Initialize Cloud Firestore through Firebase
var db = firebase.firestore();
function submitCountry(){
console.log('in funtion');
db.collection("cities").doc("asdasLA").set({
name: "Los Angeles",
state: "CasdasA",
stasdaate: "CasdasdasA",
stasaasddaate: "CAasd",
country: "USA"
})
.then(function() {
console.log("Document successfully written!");
})
.catch(function(error) {
console.error("Error writing document: ", error);
});
}
</script>
when i refresh my page it show the uncaught error.
{code: "app/duplicate-service", message: "Firebase: Firebase service
named 'firestore' already registered (app/duplicate-service).", name:
"firestore", stack: "firestore: Firebase: Firebase service named
'fires…m/firebasejs/5.3.0/firebase-firestore.js:1:326255"} firebase #
index.esm.js:17591 (anonymous) # index.esm.js:41 index.esm.js:17591
Uncaught Error: Cannot instantiate firebase-firestore - be sure to
load firebase-app.js first.
after clicking my save button it shows the error mention below.
when i use the same code on simple project without any JS or Bootstrap it works fine but same code i placed in My real project with Bootstrap it shows errors
[Intervention] Slow network is detected. See for more details.
Fallback font will be used while loading:
By doing
<script src="https://www.gstatic.com/firebasejs/5.4.2/firebase.js"/></script>
<script src="https://www.gstatic.com/firebasejs/5.3.0/firebase-firestore.js"></script>
you load the 'firestore' Firebase service twice, see the doc: https://firebase.google.com/docs/web/setup
You should either do
<script src="https://www.gstatic.com/firebasejs/5.4.2/firebase.js"></script>
or
<!-- Firebase App is always required and must be first -->
<script src="https://www.gstatic.com/firebasejs/5.4.2/firebase-app.js"></script>
<!-- Add additional services that you want to use -->
<script src="https://www.gstatic.com/firebasejs/5.4.2/firebase-firestore.js"></script>
Also note that in your code you have mixed versions (i.e. 5.4.2 and 5.3.0). Most probably something to avoid.
Following your comment below, in order to check that it writes correctly to the db, modify you code as follows and just open the HTML page (the set() method will be triggered automatically)
<script src="https://www.gstatic.com/firebasejs/5.4.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.4.2/firebase-firestore.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: ".",
authDomain: ".",
databaseURL: ".",
projectId: ".",
storageBucket: ".",
messagingSenderId: ".[enter image description here][1]"
};
firebase.initializeApp(config);
// Initialize Cloud Firestore through Firebase
var db = firebase.firestore();
db.collection("cities").doc("asdasLA").set({
name: "Los Angeles",
state: "CasdasA",
stasdaate: "CasdasdasA",
stasaasddaate: "CAasd",
country: "USA"
})
.then(function() {
console.log("Document successfully written!");
})
.catch(function(error) {
console.error("Error writing document: ", error);
});
}
</script>

ReactJS app authentication: Firebase+FirebaseUI Uncaught Error: Firebase App named '[DEFAULT]-firebaseui-temp' already exists

I'm having trouble with my code. I'm building a one page web app in ReactJS with 3 tabs.
When the user goes to one tab, the authentication form from FirebaseUI should show up. The thing is that it's working only the first time and the second time, if I change to another tab and come back, it crashes, React re-renders the component that renders the div with the authentication form and throws the error:
"firebase.js:26 Uncaught Error: Firebase App named '[DEFAULT]-firebaseui-temp' already exists."
My index.html is :
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="./src/favicon.ico">
<script src="https://www.gstatic.com/firebasejs/3.4.1/firebase.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "AIzaSyAdyeoTYNF0xLK37Zv3nEGHWCKNPQjSPsI",
authDomain: "xxxx.com",
databaseURL: "xxxxx.com",
storageBucket: "xxxxxx.appspot.com",
messagingSenderId: "xxxxxx"
};
firebase.initializeApp(config);
</script>
<script src="https://www.gstatic.com/firebasejs/ui/live/0.5/firebase-ui-auth.js"></script>
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/live/0.5/firebase-ui-auth.css" />
<title>Flockin</title>
</head>
<body>
<div id="root" class="container"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` in this folder.
To create a production bundle, use `npm run build`.
-->
</body>
</html>
The module that has the Firebase code and fills the div is on another file on a modules directory:
var firebase=global.firebase;
var firebaseui=global.firebaseui;
var FirebaseUIManager=function(){
// FirebaseUI config.
var uiConfig = {
'signInSuccessUrl': '/archive',
'signInOptions': [
// Leave the lines as is for the providers you want to offer your users.
firebase.auth.FacebookAuthProvider.PROVIDER_ID,
firebase.auth.EmailAuthProvider.PROVIDER_ID
],
// Terms of service url.
'tosUrl': '<your-tos-url>',
};
// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());
// The start method will wait until the DOM is loaded.
ui.start('#firebaseui-auth-container', uiConfig);
var initApp = function() {
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
var displayName = user.displayName;
var email = user.email;
var emailVerified = user.emailVerified;
var photoURL = user.photoURL;
var uid = user.uid;
var providerData = user.providerData;
user.getToken().then(function(accessToken) {
document.getElementById('sign-in-status').textContent = 'Signed in';
document.getElementById('sign-in').textContent = 'Sign out';
document.getElementById('account-details').textContent = JSON.stringify({
displayName: displayName,
email: email,
emailVerified: emailVerified,
photoURL: photoURL,
uid: uid,
accessToken: accessToken,
providerData: providerData
}, null, ' ');
});
} else {
// User is signed out.
document.getElementById('sign-in-status').textContent = 'Signed out';
document.getElementById('sign-in').textContent = 'Sign in';
document.getElementById('account-details').textContent = 'null';
}
}, function(error) {
console.log(error);
});
};
initApp();
};
export default FirebaseUIManager;
And finally, the component that re-renders the form every time I go back to the tab on the componentDidMount method is:
import React, { Component } from 'react';
import FirebaseUIManager from './../modules/firebase-auth-login-manager.js';
class FlockinList extends Component {
componentDidMount(){
FirebaseUIManager();
}
render() {
return (
<div>
<div id="firebaseui-auth-container"></div>
<div id="sign-in-status"></div>
<div id="sign-in"></div>
<div id="account-details"></div>
</div>
);
}
}
export default FlockinList;
Any idea on how to solve this? Thanks!
You should not initialize a new FirebaseUI instance each time you show it:
var ui = new firebaseui.auth.AuthUI(firebase.auth());
This should be initialized externally.
If you wish to render, call
ui.start('#firebaseui-auth-container', uiConfig);
When you want to remove, call:
ui.reset();
But do not initialize a new instance each time.
you could use the useEffect hook to make sure the auth container is loaded when the start method is called :
useEffect(() => {
let ui = new firebaseui.auth.AuthUI(firebase.auth());
ui.start("#firebaseui-auth-container", uiConfig);
return () => {
ui.delete();
};
}, []);
remove the instance on unmounting.

Categories