I want to define custom functions on Firebase using firebase-tools. Is there a way to get userId from firebase-functions?
Say on this code sample, is it possible to get the user who sent the request?
const functions = require('firebase-functions');
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
I have tried getting it with the following code unsuccessfully functions.auth.user().uid.
I am quite new to both js and firebase, so go easy on me please, I am trying to learn.
You're over-simplifying the way HTTP triggers work. They have no knowledge of anything about the entity on the end making the request. It could be a user, or just some automated program. The user doesn't have to be authenticated in order to access your function.
If you want to limit access to your HTTP trigger to only authenticated users, you could try something as described in this other question. There is official sample code that shows what you need to do.
Bottom line is this. Unless you do something to safely transmit to the function who the user is (identified by an id token), then you really have no idea who they are.
Think I find a better answer from this post :
https://medium.com/super-declarative/dev-snack-testing-firebase-cloud-functions-with-user-id-tokens-83841d3f06c.
Basically 2 ways for http functions
functions.https.onRequest : You may get, if available, the token from the request and then use firebase admin api to get user UID;
functions.https.onCall for authenticated request : You get it from exposed context object
Related
I am sorry for how I have framed the question in the title but I have started programming very recently so once again, I am really sorry.
I am developing a project with React js as my front-end and node js as my backend, I have been successful in doing some basic test api calls to confirm the connection between the two but now, how am I supposed to actually process different actions. For example, while a user is logging in, I need to first check if they are an existing user or not, sign them in if they are not, deleting a user account, changing username, etc.
I tried very hard to look for relevant articles but all I can find are basic "one-time" api calls, what am I supposed to do for an entire batch of operations? From what I have understood, the process of sending a request from React to getting it processed in Node js is like this:
react js ======>
(request for operation) node js ======>
(process the operation) ======>
send a response back to react
Please correct me if there are any mistakes in my question...
Thanks a lot!
This question is really broad, so I'm going to focus in on this part at a high level:
I tried very hard to look for relevant articles but all I can find are basic "one-time" api calls, what am I supposed to do for an entire batch of operations?
I'm guessing when you talk about requests and APIs you're talking about HTTP requests and REST APIs, which are fundamentally "stateless" kinds of things; HTTP requests are self-contained, and the backend doesn't have to keep track of any application state between requests in order to speak HTTP.
But backend applications usually do maintain state, often in the form of databases. For example, many REST APIs expose CRUD (create, read, update, and delete) operations for important business entities — in fact, Stack Overflow probably does exactly this for answers. When I post this answer, my browser will probably send some kind of a "create" request, and when I inevitably notice and fix a typo I will send some kind of "update" request. When you load it in your browser, you will send a "read" request which will get the text of the answer from Stack Overflow's database. Stack Overflow's backend keeps track of my answer between the requests, which makes it possible to send it to many users as part of many different requests.
Your frontend will have to do something similar if your project does things which involve multiple interdependent requests — for example, you would need to keep track of whether the user is authenticated or not in order to show them the login screen, and you would need to hold onto their authentication token to send along with subsequent requests.
Edit: Let's walk through a specific example. As a user, I want to be able to create and read notes. Each note should have a unique ID and a string for its text. On the backend, we'll have a set of CRUD endpoints:
var express = require(“express”);
var router = express.Router();
class Note {
constructor(id, text) {
this.id = id;
this.text = text;
}
}
// This is a quick and dirty database!
notes = {};
router.put("/note/:id", function(req, res) {
notes[req.params.id] = "hello"; // TODO: accept text as well
res.send("");
});
router.get(“/note/:id”, function(req, res) {
res.send(notes[req.params.id].text);
});
module.exports = router;
Then on the client side, one could create a note and then read it like this:
// this request will create the note
fetch("http://localhost:9000/note/42", { method: 'PUT', body: 'hello note!' });
// this request will read the note, but only after it is created!
fetch("http://localhost:9000/note/42")
.then(res => res.text())
.then(res => console.log(res));
I'm trying to delete a comment using a Graph API call.
https://graph.facebook.com/[comment-id]?access_token=[access-token]&method=delete
However, in terms of access-token, I'm not sure which one to use? I have used my App's "User Access Token", "Page Access Token" and "App Token". It doesn't work for any of these.
[PS, my app has all permissions, and I have even submitted it for review]
I just wanted to know if it was even possible to delete a comment which was not posted by the application? (Because I see that Delete is only allowed for page access tokens).
So, please do let me know if it is possible to delete a comment from a user's posts. And if so, which access_token to provide.
The docs list all the neccessary Access Tokens and permissions:
https://developers.facebook.com/docs/graph-api/reference/v2.10/comment#deleting
I tried it with a user profile, it does not seem to be possible to post comments or delete them - no matter if was created by the App or manually:
Publishing comments through the API is only available for page access
tokens
For Pages, you need to use a Page Tokens with the neccessary permissions according to the docs.
It looks to me that you're doing an HTTP GET call and just putting &method=delete at the end. That's not how it works
You should do an HTTP DELETE call. So instead of doing something like $.get(...), you should do $.ajax with type: 'DELETE'
Also, make sure your token has publish_actions permission
I have a custom Google Sign In button in React (follows branding guidelines) that I need to implement into a web app. The android app already has Google Sign In implemented with the BE and requires the authorization code to be sent to the BE. I seem to have trouble accessing the authorization code (I can get the access token, id, and id_token fairly easily though).
I initialize as such:
static googleInit (googleSignInID) {
gapi.load('auth2', () => {
ThirdPartyLogInApi.auth2 = gapi.auth2.init({
// Retrieve the singleton for the GoogleAuth library and set up the client.
client_id: `${googleSignInID}.apps.googleusercontent.com`,
})
})
}
In my React component, I attach a click handler to a React ref (as I've seen in other stackoverflow problems).
componentDidMount () {
// element, options, success, failure
ThirdPartyLogInApi.auth2.attachClickHandler(
this.button,
{},
this.onGoogleSuccess,
this.setProcessingToFalse
);
}
In the success callback (this.onGoogleSuccess), I am able to call googleUser.getBasicProfile() to get user information and googleUser.getAuthResponse(true) to get id_token and access_token, but I need the authorization code too.
I'm at my wits end with Google's documentation on this - can someone point me in the right direction? I don't want to switch the entire auth flow to use gapi.auth2.authorize, as I do need the user information.
Thanks
EDIT: Is it even possible to access the authorization code? It seems like Google abstracts away that step and just returns the id_token right away. I just need something that looks like:
4/RQFWJLGd3sJQrgxuRaguzJy2yiUV4fAqVGftRSUYuqc
I'm using npm package 'request' to make API calls. Upon initial login, I should receive a cookie back, I need to store that cookie indefinitely to make subsequent calls.
I'm doing this in Python with requests like so:
#set up the session
s = requests.session()
#logs in and stores the cookie in session to be used in future calls
request = s.post(url, data)
How do I accomplish this in node? I'm not tied to anything right now, the request package seems easy to work with, except I'm having issues getting known username and passwords to work, that said, I'm sure that's mostly my inexperience with JS/node.js.
This is all backend code, no browsers involved.
I need to essentially run a logon function, store the returned encrypted cookie and use for all subsequent calls against that API. These calls can have any number of parameters so I'm not sure a callback in the logon function would be a good answer, but am toying with that, although that would defeat the purpose of 'logon once, get encrypted cookie, make calls'.
Any advice, direction appreciated on this, but really in need of a way to get the cookie data retrieved/stored for future use.
The request package can retain cookies by setting jar: true -
let request = request.defaults({jar: true})
request('http://www.google.com', function () {
request('http://images.google.com')
})
The above is copied near-verbatim from the request documentation: https://github.com/request/request/blob/master/README.md#requestoptions-callback
I need to retrieve a facebook page's list of posts (feed) using their javascript SDK, just like they explain in their docs: https://developers.facebook.com/docs/graph-api/reference/v2.4/page/feed
/* make the API call */
FB.api(
"/{page-id}/posts",
function (response) {
if (response && !response.error) {
/* handle the result */
}
}
);
I need it to be my website's "news section", so users should see it even if they are not connected to facebook.
The problem
Cool, but there is a problem... It returns: An access token is required to request this resource.
Holy cow... I'd like to get some access token for you #facebook, but my app doesn't make use of your authentication tools/plugins.
ANYWAY, I tried with FB.getLoginStatus(); but doesn't work, because the only way it can return an access_token is if the user is actually connected to the application. My users may not even be logged to facebook!
So, ¿How can I get an access_token to be stored into a variable, and later be used to get /{my-page}/posts?
I've already payed a look to this SO question, but it doesn't solves my problem, simply because there are no such "generic tokens".
I've also read https://developers.facebook.com/docs/facebook-login/access-tokens/ and that also relies on tokens generated through facebook login methods... So, can't I display a list of fb page's posts in my website, without being connected into facebook, hence an application?
ADD: My app is build with angularJS, I'm not dealing with server-side code. I shall rely purely on javascript methods.
You could either use an page or an app access token, but as you'd be using them on the client-side, neither of them are an option.
See
https://developers.facebook.com/docs/facebook-login/access-tokens#apptokens
https://developers.facebook.com/docs/facebook-login/access-tokens#pagetokens
Note that because this request uses your app secret, it must never be made in client-side code or in an app binary that could be decompiled. It is important that your app secret is never shared with anyone. Therefore, this API call should only be made using server-side code.
I'd strongly recommend to build a simple server-side script (PHP for example) to proxy the request to the Graph API. You could then call this via AJAX for example and load the posts asynchronously (and alse get rid of the FB JS SDK!). There is NO way to handle this in a secure manner if you don't want to use FB Login for all of your users (which also doesn't make much sense IMHO).
I think it's straightforward :)
Since pages' posts are always public, it only needs a valid access token to retrieve page posts.
Quoting what you've written:
So, ¿How can I get an access_token to be stored into a variable, and later be used to get /{my-page}/posts?
You only require an access token.
My suggestion would be;
- Generate an access token for yourself (no extra permission needed)
- request page-id/posts
This way you don't require other users to be connected to facebook, you can simply requests page-id/posts to retrieve posts with access token you generated for yourself.
I hope it solves your problem :D
TIP: As long as posts are public, you only require a valid access token, it doesn't need to be user or page specific.