Firebase Auth and Caledar API - firebase

I am trying to log in a user and create an event in their calendar.
I am using Firebase Auth and Google Calendar API. I am not sure how I can use Firebase Access Token to create event for the user.
<script type="text/javascript">
initApp = function() {
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
user.getIdToken().then(function(accessToken) {
//how can I use this accessToken to create event in the calendar?
});
} else {}
}, function(error) {});
};
window.addEventListener('load', function() {
initApp();
});
</script>
I have a script that can log in a user and I have a script that can create an event (code not posted because the code is very similar to the attached links). How can I combine these two tasks?
From reading the documentation, I know that I have to add Calendar scopes and discovery documents to the auth script. However, I am struggling with the next steps.
Thanks for the help!

You can't use the Firebase ID token to call Google Calendar APIs.
You need to use the Google JS library to sign in to Google and to call calendar APIs. You can then get the Google ID token token to sign in with Firebase.
// Build Firebase credential with the Google ID token.
const credential = firebase.auth.GoogleAuthProvider.credential(
googleUser.getAuthResponse().id_token);
// Sign in with credential from the Google user.
firebase.auth().signInWithCredential(credential)
.then((authResult) => {
// User signed in with Firebase.
})
.catch((error) => {
// Error while signing in.
});

Related

FIrebase Authentication | Any triggers for when a user Signs in? [duplicate]

I see how execute a Cloud Function on user account creation:
exports.myFunction = functions.auth.user().onCreate(event => {
But I need my function to execute when the user logs in. Is there a onLogin trigger?
And can someone with 1500 points create a tag for firebase-cloud-functions?
There's no event for login, because only the client side can define exactly when a login happens. Different clients may define this in different ways. If you need to trigger something on login, figure out when that point is in your app, then trigger it from the client via a database or HTTP function.
This worked in the controller:
firebase.auth().onAuthStateChanged(function(user) { // this runs on login
if (user) { // user is signed in
console.log("User signed in!");
$scope.authData = user;
firebase.database().ref('userLoginEvent').update({'user': user.uid}); // update Firebase database to trigger Cloud Function
} // end if user is signed in
else { // User is signed out
console.log("User signed out.");
}
}); // end onAuthStateChanged
And this is the trigger in the Cloud Function:
exports.getWatsonToken = functions.database.ref('userLoginEvent').onUpdate(event => { // authentication trigger when user logs in
I made a location in Firebase Database called userLoginEvent.
One confusing bit is that in the functions console it's /userLoginEvent but in your code you must leave out the slash.
You can create your own analytics event, like login and used it as the trigger for your cloud function.
Then in your app, when the user successfully authenticate you use firebase analytics to send an event with the name you defined, like login
exports.sendCouponOnPurchase = functions.analytics.event('login').onLog((event) => {
const user = event.user;
const uid = user.userId; // The user ID set via the setUserId API.
});
You can trigger an https onCall firebase cloud function on login
ex: This is your login button trigger function which calls an https onCall function after authenticating the user.
_login() {
firebase
.auth()
.signInWithEmailAndPassword(this.state.email, this.state.password)
.then(function (user) {
var addMessage = firebase.functions().httpsCallable('myCloudFunctionName');
addMessage("whatever variable I want to pass")
.catch(error => {
console.log("I triggered because of an error in addMessage firebase function " + error)
)}
}).catch(error => {
console.log(error);
});
}
There is also another way you can do this inside Google Cloud if you enable Identity Platform for a project. Then you can follow this guide:
https://cloud.google.com/functions/docs/calling/logging
And trigger cloud functions for any of these Firebase Authentication events:
https://cloud.google.com/identity-platform/docs/activity-logging?authuser=1&_ga=2.226566175.-360767162.1535709791#logged_operations
The only problem I've just noticed is that the logs generated for Sign In event do not include the firebase app id or anything to determine which client the user logged in on which is really annoying as this was the main reason we needed to do this!

How can I retrieve the authentication data of a user when using a Firebase callable function?

My mobile app built in Flutter uses google login to register users. From within this app I am calling a Firebase cloud function (called questionAnswer) using the Cloud Functions Plugin for Flutter.
If I understand correctly from this documentation, the https request should automatically include the Firebase authentication of the user.
How can I retrieve the authentication information of the user from within the Cloud Function? I need it in order to access data associated with that specific user in a Firebase Cloud Database. Should I include the google auth token as a parameter in the https request?
Here is my code in the Flutter app:
final HttpsCallable callable = CloudFunctions.instance.getHttpsCallable(
functionName: 'questionAnswer',
);
fetchHttps() async {
dynamic resp = await callable.call();
print(resp);
}
This is the code in the Cloud Function
exports.questionAnswer = functions.https.onCall(() => {
console.log('addNumbersLog', "holaLog");
return answer;
});
As you can see from the documentation, auth information is in the second parameter passed to the function. You will need to declare and use it:
exports.questionAnswer = functions.https.onCall((data, context) => {
console.log('addNumbersLog', "holaLog");
console.log(context.auth);
return answer;
});
context here is a CallableContext object.
You can obtain the uid of the user from the CallableContext parameter, which is passed to your onCall handler as the second argument.
From there on you can retrieve the Firebase UserRecord using the .getUser() method and passing in the uid.
exports.questionAnswer = functions.https.onCall((data, { auth }) => {
admin.auth().getUser(auth.uid)
.then((userRecord) => {
// See the UserRecord reference doc for the contents of userRecord.
console.log('Successfully fetched user data:', userRecord.toJSON());
})
.catch(function(error) {
console.log('Error fetching user data:', error);
});
});
});

Firebase Authentication with Google Identity (GoogleYOLO)

Is it possible to combine Google Identity (GoogleYOLO) with the Firebase Authentication web stack? If so, how? Thanks!
You can sign in with googleyolo using Firebase Auth as follows:
hintPromise.then((credential) => {
if (credential.idToken) {
// Initialize firebase Auth credential with Google ID token
// obtained from googleyolo.
const cred = firebase.auth.GoogleAuthProvider.credential(credential.idToken);
// Sign in with
return firebase.auth().signInWithCredential(cred);
}
throw new Error;
}).then((result) => {
// User signed in.
}).catch((error) => {
// Handle error.
});
Building on #bojeil's reply, the ID token required by Firebase's signInWithCredential function exists within the credential property of the credential object. Therefore, rather than retrieving the token using credential.idToken, you must retrieve the token with credential.credential. Here is a sample function below using Firebase V8.
// firebase V8
function handleCredentialResponse(credential) {
if (credential) {
const cred = auth.GoogleAuthProvider.credential(credential.credential);
// Sign in with credential from the Google user.
return auth().signInWithCredential(cred);
}
}
The credential param is a credential response returned from the Google one-tap function callback.
google?.accounts.id.initialize({
client_id: your-google-app-client-id.apps.googleusercontent.com,
callback: handleCredentialResponse,
});
google?.accounts.id.prompt((notification) => {
console.log(notification);
});

Google Sign-In using Firebase in React Native

Note the question might be long because of the need for explanation otherwise it might be very vague and lead to same old answers.
I am having problem in creating a Google Sign-In page in React Native using firebase. Based on firebase documentation:
With the updates in the 3.1.0 SDK, almost all of the JavaScript SDK’s
functionality should now work smoothly in React Native. But there are
a couple caveats:
"Headful" auth methods such as signInWithPopup(), signInWithRedirect(), linkWithPopup(), and linkWithRedirect() do not
work in React Native (or Cordova, for that matter). You can still sign
in or link with a federated provider by using signInWithCredential()
with an OAuth token from your provider of choice.
which means I cannot use following code in my React Native project:
var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider).then(function(result) {
// This gives you a Google Access Token. You can use it to access the Google API.
var token = result.credential.accessToken;
// The signed-in user info.
var user = result.user;
// ...
}).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
// ...
});
Then with some googling and searching over dozens of stackoverflow, I found following way to use use Google SignIn using Firebase API
in React Native project as:
const provider = firebase.auth.GoogleAuthProvider;
const credential = provider.credential(token);
firebase.auth().signInWithCredential(credential)
.then((data) => {
console.log('SUCCESS', data);
})
.catch((error) => {
console.log('ERROR', error)
});
Now in just above code, you might have noticed token in following line:
const credential = provider.credential(token);
So based on firebase documentation, token is obtained as follows:
// `googleUser` from the onsuccess Google Sign In callback.
var token = googleUser.getAuthResponse().id_token;
So my question is how do I obtain that token using GoogleUser object or whatever it is in React Native? Or is there another way?
I am going to assume you've added GoogleSignin to your project. If not, you can find a pretty good instruction here
The callback that Google provides has an item, called idToken, which can be used to login via google into your firebase. Once you have returned that object from Google Signin, EG
GoogleSignin.signIn()
.then((user) => { this.loginWithGoogle(user) });
You can simply use this user object's idToken as a credential,
loginWithGoogle = (user) => {
var credential = firebase.auth.GoogleAuthProvider.credential(user.idToken);
and then log into firebase using that credential
firebase.auth().signInWithCredential(credential).then(u => {
//blah blah bleep
}
Hope this helps.

Access scope data after Firebase authentication

I authorized the calendar api in my google sign in auth, using the following code (Angularfire2):
let auth = new firebase.auth.GoogleAuthProvider();
auth.addScope('https://www.googleapis.com/auth/calendar');
this.afAuth.auth
.signInWithPopup(auth).then((data) => {
console.log(data); // nothing about calendar here
});
Is there any way to access authorized scopes using FirebaseAuth?
For example, access the calendar data after the user signs and authorizes the calendar auth.
If you check out the reference docs, you'll see that there are examples for each provider, which demonstrate how to obtain the third-party OAuth token:
// Using a redirect.
firebase.auth().getRedirectResult().then(function(result) {
if (result.credential) {
// This gives you a Google Access Token.
var token = result.credential.accessToken;
}
var user = result.user;
});
Once you have the third-party token, you can use that directly against their APIs.

Resources