Is there a way to integrate an Expo app with firebase dynamic links without detaching? - firebase

Is there a way to integrate an Expo app with firebase dynamic links without detaching.

If you need to create new dynamic links on the fly you could use REST API to do it. In the much more likely scenario that you only need your app to open Firebase's dynamic links, you don't need to do anything other than configuring your Expo App to handle universal links (ie: deeplinks using http/https).
The checklist is something like this:
1. Configure your app.json
For Android, add the intentFilters property to your android property:
"android": {
"intentFilters": [
{
"action": "VIEW",
"data": [
{
"scheme": "https",
"host": "<your-domain>",
"pathPrefix": "/"
},
],
"category": [
"BROWSABLE",
"DEFAULT"
],
"autoVerify": true // required to work on newer android versions
}
]
]
For iOS, add the associatedDomains property to ios:
"ios": {
"associatedDomains": ["applinks:<your-domain>"]
}
2. Configure your domain to allow links from it to be handled by the apps
Android and iOS will allow your app to open links from your domain if you serve a configuration file from a specific location:
Android: https://<your-domain>/.well-known/assetlinks.json
iOS: https://<your-domain>/.well-known/apple-app-site-association
assetlinks.json will look something like this:
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "<android-package-name>",
"sha256_cert_fingerprints":
["<your-sha256-certificate-fingerprints>"]
}
}]
And the apple-app-site-association like this:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "<your-team-id>.<ios-bundle-identifier>",
"paths": [ "*" ]
}
]
}
}
You can read more about these files here and here.
To obtain the SHA256 fingerprints of your app’s signing certificate you can use the keytool:
keytool -list -v -keystore <your-key-file>
After you enter your keystore password, it will print many of the keystore information including the SHA256 fingerprints.
If your site is hosted on Firebase both assetlinks.json and apple-app-site-association can be generated automatically if you create the Apps on your Firebase's project. Otherwise, just put these files on the root of your domain.
3. Create a Firebase dynamic link
I think this is step is mostly self explanatory but just a few notes:
Set up your short URL link: in the end you will have / that you send to your users
Set up your Dynamic Link: here you define your deelink (the link you want your app to handle)
Define link behavior for iOS: you mostly likely want to click on 'Open the deep link in your iOS App' and select your App from the list (if you haven't yet, create one App for each platform on your project)
Define link behavior for Android: same as previous but with a few more options to select
Configure (or not) campaign tracking and you're done.
Remember that you always should test your deeplinks by clicking instead of by entering directly on the browser. You may send the link to yourself on the WhatsApp or put on some notes app, for example.
Others resources that might be helpful:
https://docs.expo.io/versions/latest/workflow/linking/
https://reactnavigation.org/docs/deep-linking/

In addition to Pedro Andrade's instructions:
1.) Firebase requires the following details under your app > project settings for dynamic links to work.
Android: SHA 256 (App signing key certificate fingerprint) - this can be retrieved via play store > your app > App Integrity > SHA 256
iOS: App ID Prefix (Team ID): developer.apple.com > Certificates, Identifiers & Profiles > your app id > App ID Prefix
Surprisingly, these are mentioned almost nowhere in the docs, but do come up in stackoverflow results and other answers when googling errors that debugging preview links result in:
Android app '<bundle id>' lacks SHA256. AppLinks is not enabled for the app. Learn more.
iOS app '<bundle id>' lacks App ID Prefix. UniversalLinks is not enabled for the app. Learn more.
You can view debugging preview links by adding ?d=1 to your dynamic links.
https://firebase.google.com/docs/dynamic-links/debug
2.) Even if you use a page.link-style domain provided by firebase for your dynamic links, your associatedDomain/intentFilter domains in app.json should still be your actual domain
i.e if you're generating my-app.page.link shortLinks, that are dynamic links to my-app.com, you should use my-app.com in app.json

Pedro Andrade's solution works! Partially...
Explaining:
You must NOT add your dynamic link domain in intentFilters and associatedDomains, because it makes the app to open the link directly in the app, so, the dynamic link is not processed and you don't have access to the link generated by the dynamic link.
It works partially because of this: the dynamic link needs to be opened by the browser (chrome or safari) before being opened in the app.
Example: Open "<your-domain>.page.link/XLSj" in browser, browser will direct to generated link: "<your-domain>.com/params/54" to configured deep link.
I don't know any other way to 'read' the dynamic link by expo in managed workflow.

Related

Angular Service Worker stuck in Safari after logout

We have a WebApp developed with Angular 14. It is deployed on Azure Blob Storage (static website).
Authentification is done with the msal library for javascript. Azure AD B2C is used as identity provider.
When we logout we call msalService.logoutRedirect() which works fine for all devices except for iPhones using the Safari browser. On iPhone/Safari it sometimes gets stuck (mostly when we had the phone locked for a few minutes first). Safari then displays a "neverending" network request - but I am convinced that the actual problem is some code in the service worker, as Safari gets completely frozen and you cannot even enter anything in the Console.
We are using Angular Service Worker to provide a PWA and everything is working fine if we serve the app without Service Workers.
I tried to take a look at ngsw/state (which usually works) but as soon as the bug occurs, this site is not reachable (I assume because Safari is stuck).
For me this looks like the service worker code is stuck in some loop (there are no errors shown in the console). When I then manually try to reload the page we get the following errors in the console: .
How can I find out what causes the problem here? I tried to debug the ngsw-worker.js file but it's almost 2k lines, so it's not that easy. Is there any simpler way to debug it?
Update:
This is how the ngsw-config.json looks like:
{
"$schema": "./node_modules/#angular/service-worker/config/schema.json",
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.ico",
"/index.html",
"/manifest.webmanifest",
"/*.css",
"/*.js"
]
}
}, {
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/**",
"/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
]
}
}
]
}
We are using google-fonts and fetch it from fonts.googleapis.com.
When we logout and the bug occurs the browser displays that it tries to load the google fonts - it is stuck there. Is it possible that it somehow thinks the google-fonts file should be in cache and it tries to fetch it but since it isn't there, it loads endlessly?
Update: I found a forum post that sounds very similar to the problem we have, unfortunately, it seems they never found a solution: apple forum
You could try to clone the msal library and change the code in the navigation client to always use replace instead of assign. Could be worth a shot since it helped me in the react oidc library i used.

Firebase Log-in events

I want to see Who and When login to the Firebase from UI side, as administrator.
It is not related data access from app etc.
So, I login to https://firebase.google.com/ as User/Manager/Admin and want to see it in logs.
It should be in GCP project related to firebase, if so how can I find it - did saw in Log explorer.
Or it should be in Firebase UI?
thank you in advance.
I would give you a workaround. You can use Firebase Management API which is in beta.
Consider you have to watch a project.
You can make a request like below to get the Project Details.
GET https://firebase.googleapis.com/v1beta1/projects/{YourProjectID}
Sample Response:
{
"projectId": "*****************",
"projectNumber": "*****************",
"displayName": "Sample App",
"name": "projects/*****************",
"resources": {
"hostingSite": "*****************",
"realtimeDatabaseInstance": "*****************"
},
"state": "ACTIVE",
"etag": "1_d15ff4d3-727e-431c-8eba-f33957805f23"
}
In the response, you have a key called ETAG. Basically, this changes whenever the project is opened by someone.
You cannot get who is logged-in or other details.
You can only know someone has opened, changed or made some operations in the project, using ETAG.
You can simply store the ETAG in your server and poll for the change.
If it is changed, then someone might have used the Project.
If you want the Updated Time of the project along with it, you can try this,
https://cloud.google.com/resource-manager/reference/rest/v3/projects/get

Universal link common to both Full App and AppClip

I want to use universal link common to both Full App and AppClip ex: https://example.com, and the desired scenario is as follows:
  1. When users install AppClip, scan this link will show AppClip Card
  2. When users install Full App, scan this link will show Full App
This is the content in the file https://example.com/.well-known/apple-app-site-association I have installed:
`{
"applinks": {
"apps": [],
"details": [{
"appID": "teamId.xxx.yyy.Example",
"paths": ["*"]
}]
},
"appclips": {
"apps": ["teamId.xxx.yyy.Example.Clip"]
}
}
`
Here is the Associated Domains setting on the Xcode side:
Full App: applinks:example.com
AppClip: appclips:example.com
But the results are not as expected, when scanning the link, it always shows the AppClip Card with the message: "This app clip is not currently available in your country or region" (even when I don't have AppClip installed), and Every time you test the main app, you will have to use “Clear Experience Cache”
Please help, thanks a lot.

Firebase 3rd-party AuthProvider (Google/Facebook/etc) login with chrome extension manifest v3

Manifest version 3 for Chrome extensions have been killing me lately. Been able to navigate around it so far, but this one has really stumped me. I'm trying to use Firebase authentication for a Chrome extension, specifically with 3rd party auth providers such as Google and Facebook. I've setup the Firebase configuration for Login with Google and created a login section in the options page of the Chrome extension and setup the Firebase SDK.
Now, there are two login options when using an auth provider, signInWithRedirect and signInWithPopup. I've tried both of these and both have failed for different reasons. signInWithRedirect seems like a complete dead end as it redirects to the auth provider, and when it attempts to redirect back to the chrome-extension://.../options.html page, it just redirects to "about:blank#blocked" instead.
When attempting to use signInWithPopup, I instead get
Refused to load the script 'https://apis.google.com/js/api.js?onload=__iframefcb776751' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
In v2, you could simply add https://apis.google.com to the content_security_policy in the manifest. But in v3, the docs say
"In addition, MV3 disallows certain CSP modifications for extension_pages that were permitted in MV2. The script-src, object-src, and worker-src directives may only have the following values:"
self
none
Any localhost source, (http://localhost, http://127.0.0.1, or any port on those domains)
So is there seriously no way for a Google Chrome extension to authenticate with a Google auth provider through Google's Firebase? The only workaround I can think of is to create some hosted site that does the authentication, have the Chrome extension inject a content script, and have the hosted site pass the auth details back to the Chrome extension through an event or something. Seems like a huge hack though and possibly subject to security flaws. Anyone else have ideas??
Although it was mentioned in the comments that this works with the Google auth provider using chrome.identity sadly there was no code example so I had to figure out myself how to do it.
Here is how I did it following this tutorial:
(It also mentions a solution for non-Google auth providers that I didn't try)
Identity Permission
First you need permission to use the chrome identity API. You get it by adding this to your manifest.json:
{
...
"permissions": [
"identity"
],
...
}
Consistent Application ID
You need your application ID consistent during development to use the OAuth process. To accomplish that, you need to copy the key in an installed version of your manifest.json.
To get a suitable key value, first install your extension from a .crx file (you may need to upload your extension or package it manually). Then, in your user data directory (on macOS it is ~/Library/Application\ Support/Google/Chrome), look in the file Default/Extensions/EXTENSION_ID/EXTENSION_VERSION/manifest.json. You will see the key value filled in there.
{
...
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgFbIrnF3oWbqomZh8CHzkTE9MxD/4tVmCTJ3JYSzYhtVnX7tVAbXZRRPuYLavIFaS15tojlRNRhfOdvyTXew+RaSJjOIzdo30byBU3C4mJAtRtSjb+U9fAsJxStVpXvdQrYNNFCCx/85T6oJX3qDsYexFCs/9doGqzhCc5RvN+W4jbQlfz7n+TiT8TtPBKrQWGLYjbEdNpPnvnorJBMys/yob82cglpqbWI36sTSGwQxjgQbp3b4mnQ2R0gzOcY41cMOw8JqSl6aXdYfHBTLxCy+gz9RCQYNUhDewxE1DeoEgAh21956oKJ8Sn7FacyMyNcnWvNhlMzPtr/0RUK7nQIDAQAB",
...
}
Copy this line to your source manifest.json.
Register your Extension with Google Cloud APIs
You need to register your app in the Google APIs Console to get the client ID:
Search for the API you what to use and make sure it is activated in your project. In my case Cloud Firestore API.
Go to the API Access navigation menu item and click on the Create an OAuth 2.0 client ID... blue button.
Select Chrome Application and enter your application ID (same ID displayed in the extensions management page).
Put this client ID in your manifest.json. You only need the userinfo.email scope.
{
...
"oauth2": {
"client_id": "171239695530-3mbapmkhai2m0qjb2jgjp097c7jmmhc3.apps.googleusercontent.com",
"scopes": [
"https://www.googleapis.com/auth/userinfo.email"
]
}
...
}
Get and Use the Google Auth Token
chrome.identity.getAuthToken({ 'interactive': true }, function(token) {
// console.log("token: " + token);
let credential = firebase.auth.GoogleAuthProvider.credential(null, token);
firebase.auth().signInWithCredential(credential)
.then((result) => {
// console.log("Login successful!");
DoWhatYouWantWithTheUserObject(result.user);
})
.catch((error) => {
console.error(error);
});
});
Have fun with your Firebase Service...

Apple App Site association not working

App Search API Validation Tool of "Apple" is not validating my domain.
https://search.developer.apple.com/appsearch-validation-tool
I am using universal links but "Link to Application" is showing me "Error".(http://www.awesomescreenshot.com/image/1719847/330979a43c4c6b2766da1e703447ee04)
Here is my "apple-app-site-association" file code.
{"applinks": {"apps": [],"details": {"XXXXXXXXXX.com.streatmanagement.threadshare": {"paths": ["*"]}}}}
Can someone please solve my query or send the sample of "apple-app-site-association" valid code?
Apple's API validation tool compares your website's association file to a store listing. If your app is not yet publicly available the error you listed will be displayed.
Your apple-app-site-association has a small typo where you specify the details (it should be an array). I also assume you're replacing the XXXX's with your app ID.
{
"applinks": {
"apps": [],
"details": [
{
"appID": "APPID.BUNDLEID",
"paths": [ "*" ]
}
]
}
}
Even if you get this error from Apple's validation tool, you can test Universal links. If your Universal Link does not work on your test device you need to inspect the device logs when you fresh install it and make sure your apple-app-site-association is available at the root of your site via https with no redirects. Sometimes there is issue if the content-type is not application/json (but the file name should remain exactly apple-app-site-association).

Resources