0

In a Firebase web app I am working on I want to get a user ID from a mail address. For that I am trying to write a cloud function. But it is not working or I am not using it properly. Here is the current code (based on some sample I found on the net):

"use strict";

import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
admin.initializeApp(functions.config().firebase);

exports.myFunc = functions.https.onRequest(function(req, resp) {
const from = req.body.sender;

admin.auth().getUserByEmail(from)
    .then(function(userRecord) {
        console.log("Successfully fetched user data:", userRecord.toJSON());
    })
    .catch(function(error) {
        console.log("Error fetching user data:", error);
    });
});

I see no issue when running "firebase deploy". Then I try to test the function, various ways as I did with the demo app I wrote following this tutorial.

For example (with both existing and non-existing mail addresses):

https://us-central1-myapp.cloudfunctions.net/myFunc
https://us-central1-myapp.cloudfunctions.net/myFunc?from=abcd@xyz.com

But in either cases I get nothing in the web console and this in the browser:

Error: could not handle the request

Any suggestion from a more experienced Firebase cloud function user would be welcome.

In fact some tutorial with sample code showing how to use getUserByEmail in a firebase cloud function would be the best.

..... Here is some more information, after further investigations .....

When using this code:

const from = req.body.sender;
admin.auth().getUserByEmail(from)

I get this error in the logs:

Error fetching user data: FirebaseAuthError: The email address is improperly formatted.

When using one of these lines of code:

admin.auth().getUserByEmail("fakemail@example.com")
admin.auth().getUserByEmail("realmail@example.com")

I get the expected result in the logs:

This for the first line (with a phony mail):

Error fetching user data: FirebaseAuthError: There is no user record corresponding to the provided identifier.

This for the second line (with an actually existing mail):

Successfully fetched user data: {
2022-01-22T07:25:04.946Z ? myFunc:   uid: 'yfC123abc....',
2022-01-22T07:25:04.946Z ? myFunc:   email: 'realmail@example.com',
.....
}

What I need is to know the way to correctly have this function accept a parameter (called from or whatever) and also know how to use the function from my original web app.

... Still more code after some more trial and errors ...

Here a new chunk of code showing my current issue:

const from = req.query.from;
// The 2 following lines produce the expected result.
// That is the mail address passed as a parameter.
console.log("from(CL):", from);
functions.logger.log("from(FL):", from);

admin.auth().getUserByEmail(from)
.then(function(userRecord) {

I get an error message, when running firebase deploy on the line with getUserByEmail reading:

src/index.ts:37:33 - error TS2345: Argument of type 'string | string[] | ParsedQs | ParsedQs[] | undefined' is not assignable to parameter of type 'string'.
  Type 'undefined' is not assignable to type 'string'.

37     admin.auth().getUserByEmail(from)

                               ~~~~

What is the correct syntax to use for the line handling the getUserByEmail call.

Michel
  • 10,303
  • 17
  • 82
  • 179
  • Hi, have you looked into [Unable to get user by email using Cloud Function for Firebase](https://stackoverflow.com/a/45243997/15774177)? – Zeenath S N Jan 19 '22 at 13:02
  • Do you see, in the console, the error that should be printed by `console.log("Error fetching user data:", error);`? – Renaud Tarnec Jan 19 '22 at 13:29
  • @Zeenath S N. Yes, the post you mention is actually one the places which helped me get started, before writing this post. Though taking a second look, I am not quite sure what is meant by "proper config json" in the answer. But I deploy and see no problem or error. – Michel Jan 20 '22 at 03:09
  • @Renaud Tarnec. No I don't see any message like that in the logs. But I see a "408 Request Timeout" in the errors. – Michel Jan 20 '22 at 03:22
  • Can you use ```firebase functions:log``` to check your logs? Also refer [docs](https://firebase.google.com/docs/functions/writing-and-viewing-logs) for more details. – Zeenath S N Jan 21 '22 at 09:07
  • @Zeenath S N. OK thanks; following your tip I have been able to make some progress. Using the logs I can now see a user ID from the email. But the only thing I can see in the browser is still "Error: could not handle the request". Beside my code only works if I hard code the mail address. This part of the code "const from = req.body.sender; admin.auth().getUserByEmail(from)..." is not working. It brings an error: "The email address is improperly formatted". At the end I want to be able to use this function from my web app. So I need to know how to call it with the proper syntax. – Michel Jan 22 '22 at 07:50
  • @Zeenath S N. I edited my post to add some more information, please have a look. – Michel Jan 22 '22 at 08:23
  • Can you use console log to fetch ```from``` before calling ```getUserByEmail``` and see what gets printed so that we can debug further? ] – Zeenath S N Jan 24 '22 at 07:09
  • On the server side, using "firebase functions:log --only myFunc" I get a long message containing: "from: undefined" (Also req.body.sender undefined as you would expect). In the web console I have this error: "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://us-central1-myapp.cloudfunctions.net/myFunc. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 408." – Michel Jan 24 '22 at 07:57
  • Did you go through these stackoverflow threads: [One](https://stackoverflow.com/questions/45611400/cross-origin-request-blocked-the-same-origin-policy-disallows-reading-the-remot?noredirect=1&lq=1), [two](https://stackoverflow.com/questions/20035101/why-does-my-javascript-code-receive-a-no-access-control-allow-origin-header-i) – Zeenath S N Jan 27 '22 at 08:47

2 Answers2

1

I had to use this:

const from = String(req.query.from);

instead of that:

const from = req.query.from;
Michel
  • 10,303
  • 17
  • 82
  • 179
0

The problem seems to be req.body ...

while passing the input as query-string: ?from=abcd@xyz.com.

I'd assume that req.query.from should carry a value, while set.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • Well, so what should the code be? "const from = req.query.from;" ? It does not seem to work. Being able to use the function in my web app is the important thing. "...?from=abcd@xyz.com" is just a way to test (that I made up). – Michel Jan 22 '22 at 08:43
  • @Michel And how shall I know what your web app is doing? What isn't in the question is generally irrelevant. You could as well use `req.body.from`, while using the `POST` instead of the `GET` verb. – Martin Zeitler Jan 22 '22 at 08:48
  • I can give you whatever needed information. But I don't think it matters what my page is doing. The only thing relevant for the question is that is needs to call this function (myFunc) providing a given mail address and getting back the corresponding user ID. This is exactly what I don't know how to do. – Michel Jan 22 '22 at 09:05
  • Using req.query.from (as you suggest) I indeed get some results, but for some reason I cannot use the information passed in req.query.from to feed getUserByEmail, please see the last part that I just added to my post. – Michel Jan 28 '22 at 06:41