Search and update document on Firebase Cloud function - firebase

I'm trying to integrate Stripe with Firebase as a backend.
I need to create stripe customer when new user signs up to my app.
for that I wrote 1 cloud function which will execute when new user created by Firebase Auth.
but in that function I'm getting Firebase auth's user.
from that I need to update my collection's document which is created for that user. (I'm storing Auth user's uid in my collection's document).
but somehow Firebase cloud function is not updating it.
Here is my Cloud function for same.
// When a user is created, register them with Stripe
exports.createStripeCustomer = functions.auth.user().onCreate(async (user) => {
const customer = await stripe.customers.create({email: user.email});
return admin.firestore().collection('fl_users').doc(user.uid).set({customer_id: customer.id});
});
I don't know what need to update how. Can you please help me to solve my problem?

Related

FIREBASE WARNING: Firebase Error. Please ensure that you spelled the name of your Firebase correctly

as you can see by the question, I am having trouble using Firebase in my app. I initialized the Firebase object and used the configuration from my Firebase account. Additionally, I have been able to authenticate users (I have a semi-functional login system going). So far, users can login to existing accounts and create new accounts. However, I am trying to store data with my user (during registration) by taking the uid from the user and using that in my Cloud Firestore. After they register, I am trying to store the other fields (firstName, lastName, school, etc.) into the Cloud Firestore under the uid.
this.props.firebase
.auth()
.createUserWithEmailAndPassword(this.state.email, this.state.password)
.then((auth) => {
this.props.firebase
.database()
.ref("users/" + auth.user.uid)
.set({data})...
It successfully creates the user but doesn't let me store the information in the Cloud Firestore and throws the error I displayed above. Can anyone help? Thank you!
Note: this.props.firebase is the reference to the firebase object instantiated with firebase.initializeApp()
Hahahaha, I suppose that I needed to actually create a real-time database in order for it to work. I had set up the Cloud Firestore while using the Realtime Database methods. Sorry to all for your troubles.

How do you read the userInfo of another user with Firebase's cloud functions?

I had in mind to create a cloud function that let a user read some of the user infos of another user under certaine conditions.
For example:
const user1 = ??? // user1 is the current user
const user1Data = await firestore().collection('Users').doc('user1.uid').get()
const user2 = ??? // user2 is the user whith user2.uid == user1Data.partnerUid
const user2Data = await firestore().collection('Users').doc('user2.uid').get()
if (user1Data.partnerEmail == user2.email && user1Data.partnerEmail == user2.email) {
// ...
// the endpoint deliver some of the user2 data to user1.
// ...
}
I have seen the documentation of Cloud functions:
https://firebase.google.com/docs/reference/functions/providers_auth_
I have seen that with the admin API we can call getUser:
admin.auth().getUser(uid)
The difference between functions.auth() and admin.auth() is not clear for me. Can we call admin within cloud functions ?
The difference between functions.auth() and admin.auth() is not clear for me.
When you import functions from firebase-functions, all that gets you is an SDK used for building the definition of functions for deployment. It doesn't do anything else. You can't access user data using functions.
When you import admin from firebase-admin, that gives you access to the Firebase Admin SDK that can actually manage user data in Firebase Authentication. You will want to use this to look up and modify users as needed, and it works just fine when running code in Cloud Functions.
The difference between functions.auth() and admin.auth() is not clear for me. Can we call admin within cloud functions ?
Basically functions.auth(), will let you trigger Cloud Functions in response to the creation and deletion of Firebase user accounts. For example, you could send a welcome email to a user who has just created an account in your app:
exports.sendWelcomeEmail = functions.auth.user().onCreate((user) => {
// ...
});
functions.auth() is from the cloud function package:
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');
Using the above package you can preform firestore, database or auth triggers that will run in response to creating data in the database or creating a new user...
// The Firebase Admin SDK to access Cloud Firestore.
const admin = require('firebase-admin');
admin.initializeApp();
The firebase admin sdk is used to access the database from privileged environments example inside cloud functions.
Check the following links:
https://firebase.google.com/docs/functions/use-cases
https://firebase.google.com/docs/functions/auth-events
https://firebase.google.com/docs/admin/setup
https://firebase.google.com/docs/functions/auth-events

Flutter - Delete Cloud function for Firebase Firestore data when user uninstall the iOS and Android app from the respective devices

I am working on flutter app and using cloud firestore to save all users list after signup. So if any user uninstall the app, i want to write delete cloud function to delete that user details automatically from firestore to avoid push notification or any other updates.
I am using firebase analytics also, so when it fire app_remove event, i need automatically trigger delete cloud function.
Please help me on backend code for this as i am not aware of backend code.
You can leverage auth trigger functions
For example, you can create `authUserDeleted´ function and handle all such actions there.
exports.authUserDeleted = functions
.runWith(runtimeOpts)
.region(regionName)
.auth.user().onDelete(async (user) => {
console.log('deleted user: ' + JSON.stringify(user));
// handle necessary actions for the deleted user
return true;
});

How to trigger a cloud function in Firebase on password change?

I am trying to trigger a Firebase cloud function when a user changes their password, be it by
changing the password (firebase.auth().currentUser. updatePassword(newPassword) ) or by reseting it (firebase.auth(). sendPasswordResetEmail(email) ). Since I am not storing password anywhere I can not use .onUpdate trigger (or any other of the triggers).
I found a similar question, but it only asked about a trigger on password change and there is no info about a workaround: Firebase cloud function listener for password change
Edit: with this trigger I want to send an email to user that their password has been changed.
Does anyone have any ideas? Is it possible at all?
What you want is totally possible, but you'll have to implement it yourself. As the link you found states, there is no built-in on-password-update account trigger... only onCreate and onDelete account triggers. Which means we have to handle it manually. I would handle it the same way you are heading - using a cloud function to send the user an email.
I would build a cloud function named something like notifyUserOfPasswordChange() and call that cloud function from your app immediately after the line of code where you call .updatePassword() or .confirmPasswordReset() (which is the finishing step after .sendPasswordResetEmail()). If I understand the point of your question - this is the real answer here. You will need to call a cloud function manually whenever you execute password update code. There's no automated trigger.
The email can be as simple or customized as you code it. If you're unsure, then start simple and have the cloud function get the target email address from the data parameter - and then use a generic message for the email body. If you feel more adventurous, consider passing the user's UID and using the Admin SDK to look up that user's registered email address & display name and then building a prettier & personalized HTML email.
As far as how to send an email from Firebase cloud functions, there are plenty of examples out there - a good sample is on Firebase's GitHub page.
Workaround
If you're using Firestore, you can use Cloud Firestore triggers as a workaround.
Step 1
Create a Cloud Function called sendEmail.
// This cloud function will get triggered when a new document is added to `emails` collection.
exports.sendEmail = functions.firestore
.document('emails/{documentId}')
.onCreate(async (snapshot, context) => {
const data = snapshot.data()
const user = data.user
if (data.changedPassword == true) {
// send email to the user saying password was changed
} else if (data.changedEmail == true) {
// send email to the user saying the email address was changed
}
})
Step 2
Write a document to your emails collection anytime the user updates their password.
// After you call .updatePassword() or .confirmPasswordReset()
// then you do this
const db = firebase.firestore();
db.collection("emails").add({
user: {INSERT USER ID HERE}",
changedPassword: true, //changedEmail: true,
})
.then((docRef) => {
// handle success
})
.catch((error) => {
// handle error
});
(Optional) Step 3
Write a Firebase Rule to protect the emails collection. The rule says: "Only allow documents to be written to the emails collection if the user field matches the authenticated user."
Summary
On the client, you'll write a new document to the emails collection anytime you want to send an email. The document will include fields for the user id and the type of email (e.g. changedPassword, changedEmail). Your cloud function will automatically send emails when documents are added to the emails collection. Firestore Rules will ensure emails are sent only to the intended user.
This system is reusable for any type of email you want to send the user. In my app, I send emails to the user when their password is changed and when their email is changed.

Cloud Functions for Firebase: can you detect app uninstall?

Is it possible to trigger a Cloud Function when the user uninstalls the app, so that we can clean up the anonymous user realtime database entry?
You can detect app uninstall for Android as an automatically collected Analytics event called app_remove. Then you could trigger a Cloud Function to run when that event occurs. You would also need to use the Firebase Admin SDK to access the database. Check out some of the Cloud Functions for Firebase GitHub samples to see examples of using Analytics triggers and using the Admin SDK. The function could work something like this:
exports.appUninstall = functions.analytics.event('app_remove').onLog(event => {
const user = event.user; // structure of event was changed
const uid = user.userId; // The user ID set via the setUserId API.
// add code for removing data
});

Resources