Change action-url in firebase authentication templates from code - firebase

I'm currently generating email verification links via a cloud function, to send them with postmark. I created a custom frontend inside my web app that is verifies the email via the .applyActionCode() function. Everything works so far, the only problem i have is the action-url.
It uses the standard url that is generated for the firebase project (https://myniceproject.firebaseapp.com/__/auth/action), but i would like to use my own domain (https://myowndomain.com/authAction) for this, that forwards the user to my custom verification component.
I'm aware that you can change the action-url by hand inside the firebase console, but i would like to change this via code so this can be applied to different environments via configs. I already looked into the actionCodeSettings parameter (Email Actions) to see what i could do via those settings. I applied the url param with my domain, but that only added the continueUrl to the query parameters.
tl;dr I'm looking for a solution to change the action-url from authentication templates to my custom domain from code instead manually in the firebase console.

As I was not able to find a native firebase way of doing this, I had to figure out my own solution. What I'm doing now is, I'm just extracting the query search parameters and building my own custom verification link that I'm sending to the user via Postmark. The Code is pretty basic and looks like this:
const firebaseVerificationLink = await admin.auth().generateEmailVerificationLink(userEmail);
const searchParams = Object.fromEntries(new URL(firebaseVerificationLink).searchParams);
const customVerificationLink = `${functions.config().url}/authAction?mode=${searchParams.mode}&oobCode=${searchParams.oobCode}`;
Maybe this helps someone else.

Related

Flutter - Create sharable profile link

I am trying to create a Social media kind of networking Flutter app in which user can share his profile link. That link must redirect directly to user's profile if app is installed else redirect to link to download app. I am using Firebase as backend. Any resources or packages to work with?
You can use the package Share to enable the user to share their profile themselves. Its really easy to use.
If you would like to share a profile you will need to provide the navigational route to get to the profile screen, then provide the user's ID/data to get/view the desired data.
As far as getting a deep link to get the user to download the app if it is not installed, you can use firebase's dynamic link feature. You can customize what the link preview looks like and says. They have really good docs that you can follow.
You could use a Firebase dynamic link.
A dynamic link is basically a link pointing to possibly 3 resources:
Web URL
Android (Google Play) App ID
iOS (App Store) App ID
So once you configure it on Firebase (it's simple to configure), when the user access the link, Firebase will employ a decision tree to decide where to send the user.
In case the access is done on a mobile device, but if the app is not downloaded, it'll send the user to the store, and after returning from the store, will send the user to the correct path you've configured, following the link.
And on the app, you can implement the SDK to handle this link and when receiving this route request, redirect the user to the right profile they want to access.
I could go through the whole process, but I suggest you check the whole Firebase documentation:
https://firebase.google.com/docs/dynamic-links
In case you have a question on that where I can explain further, just let me know.

Firebase dynamic links not working for Firebase sign in with email link (password less)

I'm using Firebase sendSignInWithEmailLink with the url generated as part of the Firebase dynamic link.
The firebase dynamic url looks like:
e.g: https://myapp.page.link/H1c4
The url from step 1 is sent as part of sendSignInWithEmailLink
User received email and clicks on the verification link.
At the end of redirection I can see that the url contains the oobCode as shown below:
https://myapp.page.link/H1c4?apiKey=&oobCode=YG2N2eLU4qGBsDeLU5cVsDrzF9qwkGzoUepInuA9pm0AAAFtfk41Nw&mode=signIn&lang=en
When my app receives the dynamic link finally, it is loosing the oobCode. My app gets
https://myapp.page.link/uEOBUnv1k4XclzwfsT5NXnGBgAA3/
The part after link/ is a custom data which I used while generating the link in step 1.
When I use isSignInWithEmailLink for validating the link in step 5, I get the result as FALSE indicating it's not a valid email link.
But if I provide the full URL from step 4 in the code(manually), the isSignInWithEmailLink returns TRUE.
I think I've done all required but Firebase dynamic link is not persisting the oobCode as part of the link sent to the app on the device.
Has anyone seen this and know what could be the problem? keen to get feedback here before reporting as an issue in Github.
Cheers
Are you using a custom dynamic link with a path, eg. https://myapp.page.link/H1c4? If so, that is currently not supported with Firebase Auth. Only custom domains with no paths are supported, eg. https://myapp.page.link.

How to properly initiate an OAuth flow for Gmail Watch?

I'm trying to initiate Gmail Watch on behalf of my site's users and also get the messages according to what historyId I get on the corresponding PubSub Topic.
I have GCP + Firebase on the backend and Angular 7 in the frontend.
I face two problems here:
Doing this on the frontend seems the right way, with grantOfflineAccess, since it asks nicely on the consent screen for the required Modify scope. However, what I get back is an auth code, and I can't find out how to get access and refresh tokens from it, and use it in the backend Cloud Functions python part.
If I try this on the backend (which works), I have to initiate the flow from python, send the redirect to Angular and pop-up the consent url there. This already seems bad, since the consent screen does not say anything about what you're granting. Then I need a redirect url, which can't be a Cloud Functions url, because I can't whitelist it (can verify the domain), so it is now handled on the Angular side and sent back. Ie. the my oauth redirect is handled in the frontend, which also doesn't seem the right way.
Could you please advise on how to do this properly?
Thanks!

Firebase Cloud Functions: Send Email via Authentication System

Firebase Authentication has a built in email service. Is it possible to fire an auth based email via Cloud Functions (admin js sdk)?
Seems like I should be able to trigger an email from noreply#my-domain.com with a custom oob code which I could then use to drive my (client-side) application.
My use case would be, when a new order .collection("orders").doc(uid) has its stage field updated/changed to 'submitted' I would like to notify a user via email that a new order is submitted. Maybe even use the oob code to mark as 'processed'?
...just trying to avoid using a 3rd party email service altogether.
you can use MailChimp to do what you are asking, since like Miles says, you will need to do a workaround in order to fix this.
I have been using MailChimp my self to send emails to each user registered in my app , i have setup a couple of emails in mailchimp and i just add to the list all the users that register to my app, so the first message will be the welcome message, then after 2 days another email and so on, you can trigger an email whenever you want, since the doc is not that clear i have made a tutorial on how to integrate it with Android.
you can find that tutorial HERE , the only thing is that is in spanish, sorry.
The idea is simple, just get your users email throught FirebaseAuth , pass that email to the mailchimp query , and then setup an email from the mailchimp website
Unfortunately, their API does not appear to support emailing users in your project. However, they have sample code for cloudfunctions to email users you can easily tweak for your needs: https://github.com/firebase/functions-samples/tree/master/quickstarts/email-users

Using Google Analytics to show subset of data for customers of web application using embed api

I'm developing an application where each 'business' has its own page (or rather many pages):
For example example.com/business/abc/
So, for the logged in business owners in the system I would like to give a feature 'View page analytics'. It would display how many visits (and maybe a couple of other things) that particular page has had.
Is there a way of doing this using the Google Analytics API with my constraints:
I don't want customers to provide their own UA code
I don't want them to require to have GA account
Customers don't need to have Google email account
I don't want to build the entire frontend and backend myself. I would rather use something existing
I've been researching this topic for hours trying to come up with a solution and can't figure out anything.
Here is what I tried and what problems happened to me:
http://ga-dev-tools.appspot.com/demos/embed-api/
This is basically exactly what I want for my customers to be displayed on my site (like in the examples), except that Embed Api tries to authorize users to their own (owned) google analytics. I want it instead to use my own Google Analytics data (or rather part of it)
The way I thought about limiting data access would be for every one of my customers to create a View in GA, Add filter to that View so only customer pages are listed there, assign User to the view, and use the Embed Api to display data from that View only. There are a couple of problems with that:
To assign User to View we need email address. And this must be either google account email, or account from a project created with Google Developers Console (application).
In other words I can't create (in any way that I know) an account that would be a shield account for my customers to a subset of my GA data that they would be interested in. It must be either a real user or a real application email address.
So what I tried to do is... I created an app in Google Developers Console, Created new OAuth Service Account. Using Ruby code (that in production app would be running on backend) I obtained OAuth token. I added this email of my OAuth service account as a User to the View
I wanted this server side generated oauth token to be used by Embed Api. That would achieve the effect that I generate the token for on my backend and user can use it without having GA user in my GA property. So I changed according to documentation the basic Embed Api example to use
gapi.analytics.auth.authorize({
container: 'auth',
clientid: 'xxx.apps.googleusercontent.com',
serverAuth: {
access_token: 'Server side generated token'
}
});
instead of
gapi.analytics.auth.authorize({
container: 'auth',
clientid: 'xxx.apps.googleusercontent.com',
});
The effects are not quite what I expected. The example doesn't show anymore (I can't see my data) but I can see in Netowrking section in Chrome that it is actually receiving real data from GA. But for unknown reason, nothing is appearing.
What I try to avoid is building a solution in which I need to build server side code that is querying GA for data, providing it to the frontend and then JS is responsible for displaying it. I would rather use Embed API but it seems not to be well suited for the use case where I don't want users to play with their UA data but rather with my own UA data limited to some scope. I would like to have at least the frontend or backend part of the solution solved. The solution doesn't need to be even Google Analytics based. Anything else that would let me achieve the use case easily and let the business owners see the effects of their marketing (traffic, sales) would be interesting as well.
Related:
Using google analytics API to show subset of data for customers of web application
Google analytics customer data?
Google Analytics API: filter by URI?
https://embeddedanalytics.com seems like something that could be useful, but their page and graphs look like from a few years ago. I would like something more pretty.
https://oocharts.com seems to be interesting because of what their docs.oocharts.com says about queries. But they don't charge anything for their product so I am skeptical of their business model and whether it is a good long-term solution. update: dead link
I don't have enough karma to post links ;)
TLDR: Displaying subset of my GA data to my customers without forcing them to become GA users and adding them to my GA account.
Any help appreciated!
Without seeing your code it's hard to know where the problem is, but using the serverAuth option definitely works. And when using the serverAuth option, you don't need to specify a client ID or container, all you need to enter is the following:
gapi.analytics.auth.authorize({
serverAuth: {
access_token: 'Server side generated token'
}
});
Here's an example that will work if you enter in a valid access token and the idsfor a view to which you have access:
http://jsbin.com/vukezoheyeco/3/edit
Note: when doing auth like this, it happens sync. This can be a gotcha if you're used to an async auth flow (like normal) and you add an event handler listening for the "success" event after calling .authorize because then your handler will never run.
I think you need the Google Analytics Super Proxy
You download the github package and upload to your own App Engine project, do some minimal configuration and then you have an interface where you can setup Google Analytics API calls which require no user login.
It provides end user URLs that you can use to construct data tables in your front end, it also provides data-table format so it slots right into Google Charts.
So for example, you have a user that needs access to visits, revenue for site section /sectionA/
You set up the GA super proxy to serve them a URL that only includes data for that section - you can try out queries here in the GA query explorer. In this case, metrics=ga:visits,ga:productRevenue and filter~=ga:page=/sectionA/
This produces an end URL with JSON data, that refreshes daily/hourly - your choice. You import this URL into your app.
The end user then logs in to your app, and sees the chart data generated from the end URL for their login. They don't need to know about GA super proxy, they just see the end resulting chart.
You could get more sophisticated by providing dropdowns to select which data chart they see, which changes the GA super proxy URL that is requested.

Resources