'ReferenceError: web3 is not defined on a client side application - web3js

I am building a client side web application with web3js and metamask. I have the web3 javascript file in a folder and metamask installed on firefox. I included the web3 file with a HTML script tag and made the metamask connection in the code.
Nevertheless, I keep getting the error "ReferenceError: web3 is not defined"
Can someone please help me with this or how to connect web3 and metamask for client side applications?
<script language="javascript" type="text/javascript" src="js/web3.min.js"></script>
window.addEventListener('load', function() {
if (typeof web3 !== 'undefined') {
web3js = new Web3(web3.currentProvider);
} else {
// set the provider you want from Web3.providers
web3js = new Web3(new Web3.providers.HttpProvider("http://10.50.0.3:22000"));
}
// Now you can start your app & access web3 freely:
startApp();
})

replace if condition with below snippet:
let web3
if(typeof window !== 'undefined' && typeof window.web3 !== 'undefined'){
//We are in the browser and metamask is running
web3 = new Web3(window.web3.currentProvider);
}
since metamask will inject web3 object and bind to window variable

Related

How to get current URL domain for react for server side rendering?

How do you get the current URL domain for react for server side rendering? Since the window object isn't accessible during SSR. React router location only gives the pathname and not the domain.
You can try adding this to your app's codebase:
if (typeof window === 'undefined') {
global.window = {}
}
You can add this to startup file which is mostly index.js

React Firebase Auth initialization problem - No Firebase App '[DEFAULT]' has been created

Feature: I want to automatically sign in with the user's profile if he or she successfully signed-in the previous web session.
Problem: I'm getting "No Firebase App" error in my React project while trying to execute firebase.auth(). The main firebase object initialization is triggered at the end of my index.js file with firebase.initializeApp(firebaseConfig). From what I can gather the firebase instance isn't properly initialized while executing authentication portion of code. Nomrally I would expect to perform the auth on the callback from the init function but there's none. So my question is what would be the best place to do the aforementioned automatic authentication/signing-in during the webpage load? Currently the authentication is performed on componentDidMount which obviously doesn't do the trick...
componentDidMount = () => {
if (localStorage.getItem("auth") == "google")
this.authenticate();
};
authenticate = () => {
var provider = new firebase.auth.GoogleAuthProvider();
firebase // <- exception
.auth()
.signInWithPopup(provider)
.then(function (result) {
// #ts-ignore
var token = result.credential.accessToken;
user = result.user;
localStorage.setItem("auth", "google");
Add in the body of your index.html:
<!-- Firebase App (the core Firebase SDK) is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/8.1.1/firebase-app.js"></script>
<!-- Add analytics if you need them -->
<script src="https://www.gstatic.com/firebasejs/8.1.1/firebase-analytics.js"></script>
<!--Add firebase dependencies you need (here i added auth and firestore) -->
<script src="https://www.gstatic.com/firebasejs/8.1.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.1.1/firebase-firestore.js"></script>
<script>
// TODO: Replace the following with your app's Firebase project configuration
// For Firebase JavaScript SDK v7.20.0 and later, `measurementId` is an optional field
var firebaseConfig = {
// ... You can find config in settings, scroll down and click on cdn
// I use cdn since it allows both external and firebase hosting
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
</script>
Then you are ready to go

Getting a firebase.database is not a function? [duplicate]

I am trying to upgrade from earlier firebase version to the latest in my ionic project. I followed this tutorial for upgrade. In step 4 from this page I am stuck on the last statement firebase.database().ref();.
Error message
TypeError: firebase.database is not a function
Below is my code. Kindly help.
...
// Initialize Firebase
this.config = {
apiKey: "some-api-key",
authDomain: "myapp.firebaseapp.com",
databaseURL: "https://myapp.firebaseio.com",
storageBucket: "project-somenumber.appspot.com",
};
...
this.authWithOAuthPopup = function(type) {
var deferred = $q.defer();
console.log(service.config); // ---> Object {apiKey: "some-api-key", authDomain: "myapp.firebaseapp.com", databaseURL: "https://myapp.firebaseio.com", storageBucket: "project-somenumber.appspot.com"}
firebase.initializeApp(service.config);
console.log(firebase); // ---> Object {SDK_VERSION: "3.0.5", INTERNAL: Object}
service.rootRef = firebase.database().ref(); //new Firebase("https://rsb2.firebaseio.com"); ---> I am getting error on this line "TypeError: firebase.database is not a function"
service.rootRef.authWithOAuthPopup(type, function(error, authData) {
if (error) {
service.authError = error;
switch (error.code) {
case "INVALID_EMAIL":
console.log("The specified user account email is invalid.");
break;
case "INVALID_PASSWORD":
console.log("The specified user account password is incorrect.");
break;
case "INVALID_USER":
console.log("The specified user account does not exist.");
break;
default:
console.log("Error logging user in:", error);
}
deferred.resolve(service.authError);
} else {
service.authData = authData;
console.log("Authenticated successfully with payload:", authData);
deferred.resolve(service.authData);
}
return deferred.promise;
});
return deferred.promise;
}
var service = this;
Update
After adding latest database library this questions problem is solved.
Updating my code here
this.authWithOAuthPopup = function(type) {
var deferred = $q.defer();
console.log(service.config);
firebase.initializeApp(service.config);
console.log(firebase);
service.rootRef = firebase.database(); //.ref(); //new Firebase("https://rsb2.firebaseio.com");
var provider = new firebase.auth.FacebookAuthProvider();
firebase.auth().signInWithRedirect(provider);
firebase.auth().getRedirectResult().then(function(result) {
if (result.credential) {
// This gives you a Facebook Access Token. You can use it to access the Facebook API.
var token = result.credential.accessToken;
console.log(result);
// ...
}
// The signed-in user info.
var user = result.user;
}).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
// ...
});
return deferred.promise;
}
I ran into this with Ionic and it turned out that I wasn't including everything when using the latest Firebase Client. If you've included Firebase as firebase-app, then the Database and Auth pieces need to be required separately since they aren't bundled when including Firebase in this way.
Add the following to your index.html after you include firebase-app.js
<script src="https://www.gstatic.com/firebasejs/3.1.0/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.1.0/firebase-database.js"></script>
Obviously you don't need to use the CDN, you could use bower (probably the preferred way with Ionic) or NPM with Browserify.
// Browserify Setup
var firebase = require('firebase/app');
require('firebase/auth');
require('firebase/database');
Snippet below taken from the Firebase Web Setup Docs
You can reduce the amount of code your app uses by just including the features you need. The individually installable components are:
firebase-app - The core firebase client (required).
firebase-auth - Firebase Authentication (optional).
firebase-database - The Firebase Realtime Database (optional).
firebase-storage - Firebase Storage (optional).
From the CDN, include the individual components you need (include firebase-app first)
A bit late to the party, but in case some one wanted to know the syntax in angular, (or Ionic 4) just add this to your .module.ts file (Note, as peterb mentioned, the /database import)
import { AuthService } from './auth.service';
import { AngularFireAuthModule } from 'angularfire2/auth';
import { AngularFireDatabaseModule } from 'angularfire2/database';
#NgModule({
imports: [
AngularFireAuthModule,
AngularFireDatabaseModule,
AngularFireModule.initializeApp(environment.firebase),
],
providers: [
]
})
i solved this issue by giving the url in the constructor
firebase.database('https://123.firebaseio.com')
First, make sure you are using
<script src="https://www.gstatic.com/firebasejs/3.1.0/firebase.js"></script>
Firebase authWithOAuthPopup has changed a little bit in the new version.
Now you don't use the ref to call authentication methods. You should be using firebase.auth() insted.
var auth = firebase.auth();
var provider = new firebase.auth.TwitterAuthProvider();
auth.signInWithPopup(provider).then(function(result) {
// User signed in!
var uid = result.user.uid;
}).catch(function(error) {
// An error occurred
});
Also faced this problem on #angular/firebase 5.1.2, solved when updated #angular/cli and all dependencies to the latest version.
For people facing similar error(this._database.native.on is not a function) in React-native -
run the pod install - after adding firebase new service(database/auth ...)
terminate the metro bundler and restart it using "npx react-native start"
run "npx react-native run-ios"
This will create a new build and the error should be gone.
Ref: https://github.com/invertase/react-native-firebase/issues/3379
Use
var firebase = require('firebase/app');
require('firebase/database');
npm install --save firebase
Then:
require("firebase/database");
You need to add all of the firebase products you are using by way of require() as shown above.
I have the same error -firebase.database is not a function- but with different situation you just need to add
above and the link of javascript that contain the Firebase configuration.
You may also try to use the defer Attribute in your script as it will not load the scripts until page elements are loaded.

Facebook Login not working in PWA app if app is in stand alone state

I am building a PWA webiste. I am using Angular JS and I used javascript facebook login in my website. But if I view my app in browser, facebook login is working. But when I add shortcut to homescreen and launch the app from the homescreen, FB login is not working. Facebook page is loading. But after entering credentials it shows blank page. Can anyone help ?
Here is my FB login code
var doBrowserLogin = function(){
var deferred = $q.defer();
FB.login(
function(response){
if (response.authResponse) {
deferred.resolve(response);
}else{
deferred.reject(response);
}
},
{scope:'email,public_profile'}
);
return deferred.promise;
}
It is opening the facebook login screen and after entering the credentials, it is showing blank. Not coming back to app.
In my manifest.json file, the display property is set to standalone.
Please help.
Don't use facebook javascript plugin, write your own flow:
1) Create a static html that will receive fb login response (ex: /fb-login-receiver.html)
It will send back login result to the application with postMessage.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
Facebook login completed.
<script type="text/javascript">
window.opener.postMessage(window.location.toString(), window.location.href);
window.close();
</script>
</body>
</html>
2) In your application write a function that will open fb login page in a popup window
this typescript example returns a promise for the access token and check if the user has allowed email access:
async loginFacebook(): Promise<string> {
let popup = window.open("https://www.facebook.com/v3.1/dialog/oauth?client_id=**<YOUR_CLIENT_ID>**&display=popup&scope=email&response_type=token,granted_scopes&auth_type=rerequest&redirect_uri=" + window.location.origin + "/fb-login-receiver.html", 'Facebook Login', 'width=500,height=500');
var promise = new Promise<string>((resolve, reject) => {
let finished = false;
let listener = (e: MessageEvent) => {
finished = true;
let url = new URL(e.data);
let hash = url.hash.substring(1);
let splitted = hash.split('&');
let dct: { [key: string]: string } = {};
for (let s of splitted) {
var spltd = s.split('=');
dct[spltd[0]] = spltd[1];
}
if (dct['granted_scopes'].indexOf('email') < 0) {
reject("Email required");
return;
}
resolve(dct['access_token']);
};
addEventListener('message', listener);
let intervalChecker = setInterval(() => {
if (popup.closed) {
clearInterval(intervalChecker);
removeEventListener('message', listener);
if (!finished) {
reject('Login canceled');
}
}
}, 10);
});
return promise;
}
This is correct behaviour because Facebook API to login user open new tab with login form. Facebook implement OAuth2 solution and for authenticate user using their API activate OAuth2 Implicit Flow. For login in the same window you must use Authorization Code, but for client side applications isn't secure beacause you will need a secret code not available for users.
Instead of open new tab you can create iframe with facebook login form and when user logged in close it and redirect.

Register service worker in angular.js application

I'm creating an app using ionic and angular.js and I'm having difficulties registering a service worker which I'm intending to use to add the new app install banner feature. I'm adding the below code on my app.js file as instructed, but I'm note getting any signals of the registration happening nor any error.
This is the code I'm adding to my app.js:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js').then(function(registration) {
//Registration was successful
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}).catch(function(err) {
//registration failed :(
console.log('ServiceWorker registration failed: ', err);
});
}
Make sure you either load the page at localhost or you have to use https
You’ll also need to serve your code via HTTPS — Service Workers are restricted to running across HTTPS for security reasons. GitHub is therefore a good place to host experiments, as it supports HTTPS.
https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker_API/Using_Service_Workers
Check if your Browser supports this feature.
if ('serviceWorker' in navigator) {
[...]
} else {
console.log("this browser does NOT support service worker");
}
This might help: http://caniuse.com/#feat=serviceworkers
If you want to see the current state of your serviceworker you could do something like this:
navigator.serviceWorker.register('/serviceworker.js', {scope: '/'})
.then(function (registration) {
var serviceWorker;
if (registration.installing) {
serviceWorker = registration.installing;
} else if (registration.waiting) {
serviceWorker = registration.waiting;
} else if (registration.active) {
serviceWorker = registration.active;
}
if (serviceWorker) {
console.log("ServiceWorker phase:", serviceWorker.state);
serviceWorker.addEventListener('statechange', function (e) {
console.log("ServiceWorker phase:", e.target.state);
});
}
}).catch(function (err) {
console.log('ServiceWorker registration failed: ', err);
});
If you're not seeing anything logged, then the most likely cause is that you're running in a browser that doesn't support service workers. In other words, the if ('serviceWorker' in navigator) check fails. You can confirm this by adding in a logging statement in an else clause associated with that if.
Which browser are you testing with? Service workers are coming to more browsers in the future, but as of right now, they're only enabled by default in the current versions of Chrome on desktop and Android platforms.

Resources