Polymer, Firebase, and Google Login, "Cannot read property push" - javascript

I'm trying to complete this tutorial but when I try to incorporate Google Login I keep getting a "Cannot read property push" error. So from looking at this answer it seems like I am not being able to log in via Google Login and so I can't use Firebase's "push".
What I can't figure out is what is preventing me from logging in.
I followed the steps in instructions and
1.) Created a new project
2.) Created OAuth client ID Credentials
3.) Created a consent screen
4.) Selected Web App for app type
5.) Authorized JS origins and redirect URIs as instructed
6.) Went to the Authentication Section (there is no Login & Auth section anymore) and added my client ID and client secret web sdk config (they no longer have a Google Client ID and Secret section)
7.) Main.js was updated to use 'google' as the provider
and I get a "Cannot read property 'push' of undefined" whenever I try to use the app. Is the code in the tutorial no longer valid? I've copied the code from the github page and replaced the firebaseURL with mine so I'm not sure what else could be wrong.
Any help would be appreciated, thanks!
As asked for
(function(document) {
'use strict';
var app = document.querySelector('#app');
app.firebaseURL = "https://***my project here***.firebaseio.com";
app.firebaseProvider = 'google';
app.items = [];
app.updateItems = function(snapshot) {
this.items = [];
snapshot.forEach(function(childSnapshot) {
var item = childSnapshot.val();
item.uid = childSnapshot.key();
this.push('items', item);
}.bind(this));
};
app.addItem = function(event) {
event.preventDefault(); // Don't send the form!
this.ref.push({
done: false,
text: app.newItemValue
});
app.newItemValue = '';
};
app.toggleItem = function(event) {
this.ref.child(event.model.item.uid).update({done: event.model.item.done});
};
app.deleteItem = function(event) {
this.ref.child(event.model.item.uid).remove();
};
app.onFirebaseError = function(e) {
this.$.errorToast.text = e.detail.message;
this.$.errorToast.show();
};
app.onFirebaseLogin = function(e) {
this.ref = new Firebase(this.firebaseURL + '/user/' + e.detail.user.uid);
this.ref.on('value', function(snapshot) {
app.updateItems(snapshot);
});
};
})(document);

While I'm not sure what the exact cause is, I can tell you that the tutorial you're following is outdated and is using the deprecated <firebase-element> (only works with Firebase 2.0). This is also stated on the element's GitHub page:
Note: This element is for the older Firebase 2.0 API.
For the latest official Firebase 3.0-compatible component from the Firebase team, see the polymerfire component.
A more recent tutorial that uses the newest polymerfire is at: Build a Progressive Web App with Firebase, Polymerfire and Polymer Components

Related

Implementing a basic non-content-based app referral system using Branch on React Native

I've been looking at the Branch SDK docs for a while now and, while they do seem to cover every base, a lot of it seems vague to me.
My app is not (currently) content-oriented. In other words, it is more of a utility app than a UGC app (again, at least for now. In the future I plan to introduce more content but that's not really relevant right now).
I currently use Fabric for analytics (as well as Firebase) and I am trying to setup a basic sharing/referral system to:
A: Increase user-driven sharing+growth
B: Track said virality in Branch (and consequently Fabric)
This is what I currently am testing for the sharing action. All of the Branch docs use examples of sharing specific content- but I don't want that! I'm trying to figure out how to configure/change the setup to share the app itself, and not some content within the app. I've copied this from the React Native docs as a start, made a couple tweaks where it made sense, but now I feel lost.
inviteFriend = async () => {
// only canonicalIdentifier is required
let branchUniversalObject = await Branch.createBranchUniversalObject('ShareFromApp', {
automaticallyListOnSpotlight: true,
title: 'What do I put here...?',
contentDescription: 'This isn\'t content, I just want to share the app'
});
let shareOptions = { messageHeader: 'Check out Foobar', messageBody: 'Check out Foobar so we can connect!' }
let linkProperties = { feature: 'share', channel: 'App' }
let controlParams = {}
let {channel, completed, error} = await branchUniversalObject.showShareSheet(shareOptions, linkProperties, controlParams);
}
How do I finish setting this up for sharing the app?
I've already setup everything on the dashboard (URI Schemes, Branch Keys, Universal Links, App Links, etc...), and I also have initialized Branch in my app as suggested by the docs in App.js componentDidMount():
this._unsubscribeFromBranch = Branch.subscribe(({ error, params }) => {
if (error) {
console.error('Error from Branch: ' + error);
return;
}
// params will never be null if error is null
console.log('Branch params: ' + JSON.stringify(params));
if (params['+non_branch_link']) {
const nonBranchUrl = params['+non_branch_link'];
console.log('non-Branch link URL: ' + nonBranchUrl);
// Route non-Branch URL if appropriate.
return;
}
if (!params['+clicked_branch_link'])
return;
// Get title and url for route
let title = params.$og_title;
let url = params.$canonical_url;
let image = params.$og_image_url;
// Now push the view for this URL
this.navigator.push({ title: title, url: url, image: image });
});
(P.S. should I move this to after the authentication flow? I've already put the Branch.setIdentity(...) behind the auth flow)
These are some of the relevant npm packages I'm using
"react-native": "0.50.3"
"react": "16.0.0"
"react-native-branch": "2.1.1"
"react-native-fbsdk": "0.6.3"
"react-native-fabric": "0.5.1"
Feel free to ask for more info if I've missed anything important. Thanks! :)

Enable users of a WebRtc app to download webrtc logs via javascript

I've seen the following:
chrome://webrtc-internals
However I'm looking for a way to let users click a button from within the web app to either download or - preferably - POST WebRtc logs to an endpoint baked into the app. The idea is that I can enable non-technical users to share technical logs with me through the click of a UI button.
How can this be achieved?
Note: This should not be dependent on Chrome; Chromium will also be used as the app will be wrapped up in Electron.
You need to write a javascript equivalent that captures all RTCPeerConnection API calls. rtcstats.js does that but sends all data to a server. If you replace that behaviour with storing it in memory you should be good.
This is what I ended up using (replace knockout with underscore or whatever):
connectionReport.signalingState = connection.signalingState;
connectionReport.stats = [];
connection.getStats(function (stats) {
const reportCollection = stats.result();
ko.utils.arrayForEach(reportCollection, function (innerReport) {
const statReport = {};
statReport.id = innerReport.id;
statReport.type = innerReport.type;
const keys = innerReport.names();
ko.utils.arrayForEach(keys, function (reportKey) {
statReport[reportKey] = innerReport.stat(reportKey);
})
connectionReport.stats.push(statReport);
});
connectionStats.push(connectionReport);
});
UPDATE:
It appears that this getStats mechanism is soon-to-be-deprecated.
Reading through js source of chrome://webrtc-internals, I noticed that the web page is using a method called chrome.send() to send messages like chrome.send('enableEventLogRecordings');, to execute logging commands.
According to here:
chrome.send() is a private function only available to internal chrome
pages.
so the function is sandboxed which makes accessing to it not possible

Chrome packaged app in-app payment api

I have created a chrome app and trying to get the list of product but I am getting internal server error. The following is a code.
function getProductList() {
console.log("google.payments.inapp.getSkuDetails");
statusDiv.text("Retreiving list of available products...");
google.payments.inapp.getSkuDetails({
'parameters': {env: "prod"},
'success': onSkuDetails,
'failure': onSkuDetailsFailed
});
}
function onSkuDetails(response) {
console.log("onSkuDetails", response);
var products = response.response.details.inAppProducts;
var count = products.length;
for (var i = 0; i < count; i++) {
var product = products[i];
addProductToUI(product);
}
statusDiv.text("");
getLicenses();
}
function onSkuDetailsFailed(response) {
console.log("onSkuDetailsFailed", response);
statusDiv.text("Error retreiving product list. (" + response.response.errorType + ")");
}
I received this same error because I mistakenly changed the app id inside buy.js to my own app id. I thought that this was the way that the in-app purchase mechanism connected to my app in the chrome web store to access the in-app purchases, but this is not the case at all. What I guess the app-id inside buy.js is the connection to the in-app purchase mechanism built inside Chrome.
So I suggest you try again with the original unmodified buy.js that comes with the test app sample zip package and see if that changes.
The consequence of all of this, is that as far as I can determine it is not possible to debug the in-app purchase flow mechanism, because you can only make it work with a already published app on which in-app purchases have been specified and as such you cannot access the Chrome console. I have not tried unpublishing the app, perhaps that might work. What you cannot do, is clone the app and load it again as an unpackaged extension (as that will of course have a different app-id).
Hope this helps.

Meteor: Authenticating Chrome Extension via DDP

I've built a Chrome Extension that takes a selection of text and when I right click and choose the context menu item, it sends that text to my Meteor app. This works fine, however, I can't figure out the process of using Oauth to authenticate users.
I'm using this package: https://github.com/eddflrs/meteor-ddp
Here is the JS within background.js (for Chrome Extension):
var ddp = new MeteorDdp("ws://localhost:3000/websocket");
ddp.connect().then(function() {
ddp.subscribe("textSnippets");
chrome.runtime.onMessage.addListener(function(message) {
ddp.call('transferSnippet', ['snippetContent', 'tag', snippetString]);
});
});
Here is the relevant portion of my other JS file within my Chrome Extension:
function genericOnClick(info) {
snippetString = [];
snippetString.push(info.selectionText);
var snippetTag = prompt('tag this thing')
snippetString.push(snippetTag);
chrome.runtime.sendMessage(snippetString);
}
And here is the relevant portion of my Meteor app:
'transferSnippet': function(field1, field2, value1, value2) {
var quickObject = {};
quickObject.field1 = value1[0];
quickObject.field2 = value1[1];
TextSnippets.insert({
snippetContent: value1[0],
tag: value1[1]
});
}
Basically I'm stuck and don't know how to go about making a DDP call that will talk to my Meteor app in order to authenticate a user
This question is a bit old, but if anyone is still looking for a solution. I had a similar problem that I was able to solve using the following plugin: https://github.com/mondora/asteroid. Here is an example of how to do it for twitter oauth:
https://github.com/mondora/asteroid/issues/41#issuecomment-72334353

How to authenticate with Google via OAuth 2.0 in a popup?

Sorry for a big edit. I am starting over as I am not stating my question correctly.
I am trying to write a client side app in HTML5. I do not want it to be hosted on a website. I am not even sure this is possible, I am fairly new to this type of application.
Anyway, I want to access Google services, which requires authenticate such as OAuth. Being that it is javascript, it sounds like OAuth2 is what I need.
I am trying to open up the google authentication in a popup (I have this part), let the user allow access, and then pass flow back to my application which can then query Google services. Problem is either 1. it asks the user to copy/paste a token into the app whenever I use response_type=code, but if I use response_type=token it requires that I redirect back to a valid URL which, since this is not hosted on a webserver, there is none.
So how can I use OAuth, and let the user grant access seamlessly?
You should have some Redirect URL defined for Google to redirect to after the authentication is done. If you cant host your pages on any web site, you can very well host it in local host.
Regarding getting the access token from the popup to the main parent window, you can setup a timer in parent window which keeps on checking the document location of the popup. Once the document location matches the Redirect URL, u can parse the access token which will will be in the URL itself.
I wrote a tutorial on exactly the same problem (using local host) yesterday and here is the link:
http://www.gethugames.in/2012/04/authentication-and-authorization-for-google-apis-in-javascript-popup-window-tutorial.html
Hope you will find it useful.
To avoid a potential click jacking, Google authentication forces you to go to a full page login. I don't think you can control that.
EDIT after comment, here is a code extracted from the Google OAuth2 page that does it:
<body>
<a href="javascript:poptastic('https://accounts.google.com/o/oauth2/auth?scope=https://www.google.com/m8/feeds&client_id=21302922996.apps.googleusercontent.com&redirect_uri=https://www.example.com/back&response_type=token');">Try
out that example URL now</a>
<script>
function poptastic(url) {
var newWindow = window.open(url, 'name', 'height=600,width=450');
if (window.focus) {
newWindow.focus();
}
}
</script>
</body>
I believe you can use google api (gapi) for Oauth in Javascript.
Here is the documentation: Authentication using the Google APIs Client Library for JavaScript
You will not require the user to copy/paste any codes and you will not require to provide a redirect uri
All you need to do is: Go to your project in Google Developers Console and generate the following:
1. Generate new Client Id and choose options 'Installed Application' and 'Other'.
2. Generate a Public API Key
Sample Code from the above documentation:
// Set the required information
var clientId = 'YOUR CLIENT ID';
var apiKey = 'YOUR API KEY';
var scopes = 'https://www.googleapis.com/auth/plus.me';
// call the checkAuth method to begin authorization
function handleClientLoad() {
gapi.client.setApiKey(apiKey); // api key goes here
window.setTimeout(checkAuth,1);
}
// checkAuth calls the gapi authorize method with required parameters
function checkAuth() {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true}, handleAuthResult); // scope and client id go here
}
// check that there is no error and makeApi call
function handleAuthResult(authResult) {
var authorizeButton = document.getElementById('authorize-button');
if (authResult && !authResult.error) {
makeApiCall();
}
}
// API call can be made like this:
function makeApiCall() {
gapi.client.load('plus', 'v1', function() {
var request = gapi.client.plus.people.get({
'userId': 'me'
});
request.execute(function(resp) {
var heading = document.createElement('h4');
var image = document.createElement('img');
image.src = resp.image.url;
heading.appendChild(image);
heading.appendChild(document.createTextNode(resp.displayName));
document.getElementById('content').appendChild(heading);
});
});
}
I've written a mini JS library for the task, take it and see if it works for you.
https://github.com/timdream/wordcloud/blob/6d483cd91378e35b54e54efbc6f46ad2dd634113/go2.js
I am recently developing another project that rely on the same script, so I am isolating this one into an independent library project ... check the progress follows (if there are).

Categories

Resources