Cloud function that triggers when an anonymous user authenticates - javascript

I am trying to send a welcome mail to a user that converted from an anonymous to a permanent user using Firebase Cloud Functions.
Prevously i followed this sample code on github which sent an email when a user was created.
The sample code uses the hook onCreate:
exports.sendWelcomeEmail = functions.auth.user().onCreate(event => {
const user = event.data;
const email = user.email;
... send the email
});
This function would trigger when the anonymous user is created (which is not what i want, since at this time the user has no email specified).
When the anonymous user converts to a permanent user the onCreate does not trigger obviously, since the user is converted not created. What cloud function do i use that triggers when an anonymous user converts to a permanent user?
When looking at the firebase cloud function reference, specifically at the namespace for Firebase Authentication functions i find that there are only two methods to work with, onCreate and onDelete. So what are my options?
Edit: I went and asked in the google group for Firebase and got this answer:
Hey there,
Thank you for your request. Please file an official request
via support channels: https://firebase.google.com/support/ You can use
real-time database or Firestore to set some flag from the client when
an anonymous user is upgraded and then listen to that node's changes
in Cloud Functions. This should get you the functionality you need.
Best regards,
So basically could just create a custom listener for it.

Related

Can't change data in Firebase Realtime Database when using Cloud Functions

I want to reset a specific value in my Firebase Realtime Database every day at 12:00 AM. I'm using Firebase Cloud Functions to do this. This is the code that I have:
exports.dailyReset = functions.pubsub.schedule('0 0 * * *').onRun((context) => {
exports.resetValue = functions.database.ref('/users/{userId}')
.onWrite((change, context) => {
var ref = change.data.ref;
ref.update({
"daily": 0
});
return ref.update({"daily": 0});
});
return null;
});
Upon testing the script, it doesn't work. It's not resetting the value in my Firebase Realtime Database. Can someone tell me how do I fix this?
It's not possible to use the Functions SDK to write to the database. functions can only be used to establish triggers that run when the triggering event occurs.
In other words, functions.database.ref('/users/{userId}').onWrite() isn't going to write anything at all.
If you want to write to Realtime Database from a nodejs program, you should use the Firebase Admin SDK to write data.
The Cloud Functions triggers in your index.js file have to be known and fixed when run firebase deploy. That means you can't dynamically create triggers from inside a Cloud Functions, as you're trying to do.
The common approaches for dynamic scheduling are:
Have a single Cloud Function that runs periodically and then executes the tasks for the past time period.
Dynamically schedule Cloud Functions with Cloud Tasks, as Doug describes in his blog post How to schedule a Cloud Function to run in the future with Cloud Tasks (to build a Firestore document TTL).
But in your case, why do you even need the onWrite trigger? Can't you just import the Admin SDK, user that to read all users, and then delete them?

Only let pre-verified users log into Firebase

Right now, I only want users who have already registered and been verified with our software to login, and I have saved the list of emails of users (stripped of special characters) inside Firebase. Currently, when the user logs in, I use the following function to check if their email is in this list:
function isEmailValid(userEmail, trueCallback, falseCallback) {
var emailHash = userEmail.replace(/[^a-zA-Z0-9]/g, "");
firebase
.database()
.ref("validEmails/" + emailHash)
.on("value", snapshot => {
if (snapshot.val()) {
trueCallback(snapshot.val());
} else {
falseCallback();
}
});
}
Although this method works, it is quite unwieldy, as the user is still able to log in initially before the function callback is called, and their email is still shown in the "Authentication" tab in Firebase.
Is there a better way to only allowed pre-verified users to log into Firebase?
I'm pretty sure this has been covered before: there currently is no way to prevent users from signing in with Firebase Authentication. But if you want to prevent them from accessing backend resources, you can check whether their email address is verified either in the server-side security rules (for Realtime Database, Storage, or Firestore), or in your own server-side code.
At I/O a demo was given of upcoming functionality in Cloud Function that would allow you to prevent signing in users without a verified email address. But I don't know when this functionality will available in a public API.
Also see:
Firebase Prevent Creating Account Before Email Verification
How to prevent user authentication in Firebase/Vue.js BEFORE email is verified
How do I lock down Firebase Database to any user from a specific (email) domain?

Which methods of Google OAuth2 API accept login_hint as a parameter

I am using the Google Sign-In JavaScript client and also referencing the Example App
The example app (app.js) tells me that login_hint is a valid option for the signIn method:
// If the user is not signed in with expected account, let sign in.
return auth2.signIn({
// Set `login_hint` to specify an intended user account,
// otherwise user selection dialog will popup.
login_hint: id || ''
});
But the reference manual does not say it does anything there but is only effective with the authorize() method. Elsewhere on the Web I see examples of it being also used with the init() method.
Can someone please clarify any/all places where the login_hint option is functionally active?
From the login_hint
Optional. If your application knows which user is trying to
authenticate, it can use this parameter to provide a hint to the
Google Authentication Server. The server uses the hint to simplify the
login flow either by prefilling the email field in the sign-in form or
by selecting the appropriate multi-login session.
Set the parameter value to an email address or sub identifier, which
is equivalent to the user's Google ID.
To set this value in PHP, call the setLoginHint function:
$client->setLoginHint('user#example.com');
Code for you:
options = new gapi.auth2.SigninOptionsBuilder();
options.setAppPackageName('com.example.app');
options.setFetchBasicProfile(True);
//options.setPrompt('select_account');
options.setLoginHint('user#example.com');
options.setScope('profile').setScope('email');
auth2.signIn(options);

How to confirm user in Cognito User Pools without verifying email or phone?

I am using Amazon Cognito Identity SDK for JavaScript (deprecated).
I created new pool without verifying email and phone_number.
By default, users aren't confirmed in Cognito User Pools, so I need to do this manually.
How to confirm user in Cognito User Pools without verifying email or phone?
I hope this will help someone else.
To do this you can add this Lambda function:
exports.handler = (event, context, callback) => {
event.response.autoConfirmUser = true;
event.response.autoVerifyEmail = true; // this is NOT needed if e-mail is not in attributeList
event.response.autoVerifyPhone = true; // this is NOT needed if phone # is not in attributeList
context.done(null, event);
};
Then navigate to AWS Cognito's General settings >> Triggers and add this Lambda function to 'Pre sign-up' - click the drop down list and select Lambda function with above code.
If you only use 'preferred_username' (if no e-mail or phone # is used) setting event.response.autoConfirmUser to true is sufficient.
Actually, AWS has recently added the ability to verify email and verify phone number in the pre-signup lambda as well. You basically need to set autoVerifyEmail and autoVerifyPhone in the lambda and they will get verified.
More info in the official documentation.
"response": {
"autoConfirmUser": boolean
"autoVerifyEmail": boolean
"autoVerifyPhone": boolean
}
I think the accepted answer is problematic. OP's question is how to confirm a user without verifying their email. But the solution will verify the user's email.
If you want to confirm a user with an unverified email (or phone), you can use AdminConfirmSignUpCommand. It is the intended way to confirm a user without having them do it, as per official docs:
Unlike ConfirmSignUpCommand, AdminConfirmSignUpCommand doesn't need a code. You can implement this command after signup in your API or as a Custom Message Trigger (effectively confirming the user when the email is sent).
Now, the user can log in, but the email must be confirmed still.

Firebase create user "manually"

I'm using the standard Email + Password auth-provider.
Through certain circumstances I have to create a firebase user manually. The flow would be something like calling a REST api with an defined email + generated password, and if succeeded sending a welcome email to the user with his password. Something like forward user registration.
I read through their docs and couldn't find much. (the new docs don't even offer a REST API section for user management.. well and just to be clear, the new "google" styled docs, pretty much suck anyway :) ).
Is there someone who has already done something similar and can help me out?
BTW: It would also be possible to create them client side through createUserWithEmailAndPassword(), but this function does automatically reauthenticate the new user, which must not happen in my scenario. Is it possible to use createUserWithEmailAndPassword() without automatically logging in the user?
You can create a new Firebase App context in your client and then call createUserWithEmailAndPassword() there:
var authApp = firebase.initializeApp({
// ...
}, 'authApp');
var detachedAuth = authApp.auth();
detachedAuth.createUserWithEmailAndPassword('foo#example.com', 'asuperrandompassword');
By adding a second argument to initializeApp you create a separate context that will not trigger re-authentication upon user creation.

Categories

Resources