I'm creating a dynamic link via API.
How can I specify to open the AppStore if the app is not installed?
here the body for my request:
{
"dynamicLinkInfo": {
"domainUriPrefix": "https://wi.page.link",
"link": "https://wiapp.com.au/faq?promocode=mypromo_code",
"iosInfo": {
"iosBundleId": "com.direce.sr",
"iosFallbackLink":"id1356389392",
"iosAppStoreId":"id1368389392",
},
"socialMetaTagInfo" :{
"socialImageLink":"https://vignette.wikia.nocookie.net/doraemon/images/b/b8/Doraemon_2005.PNG/revision/latest?cb=20151207094313&path-prefix=en",
"socialTitle":"my titu",
"socialDescription":"descripotio"
}
},
"suffix": {
"option":"UNGUESSABLE"
},
}
this works if I create the dynamic link via firebase console, where I can specify what to do if app not installed
Ok!
found the problem, is the
"iosAppStoreId":"id1368389392"
it is different value if creating from the dashboard or for API,
so the correct one when doing from, API should be without the "id"
"iosAppStoreId":"1368389392"
You can add a parameter called iosInfo, which has a property called iosAppStoreId (the app store id).
Check the documentation page here.
Related
I'm using Firebase REST APIs to create a short dynamic link on my backend. I'm writing tests (working in TypeScript) to check that functionality and I need to somehow programmatically extract the deep link nested inside the short dynamic link in order to check that I'm passing correct parameters to the mobile apps. Is it possible to do this?
Example request:
POST https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=api_key
Content-Type: application/json
{
"dynamicLinkInfo": {
"domainUriPrefix": "https://example.page.link",
"link": "https://www.example.com/data?param1=value1¶m2=value2",
"androidInfo": {
"androidPackageName": "com.example.android"
},
"iosInfo": {
"iosBundleId": "com.example.ios"
}
}
}
Example response:
https://example.page.link/WXYZ
I'm gonna get the result https://example.page.link/WXYZ in my test and then I want to do some magic (request it in a special way and parse the response?) in order to get the deep link it wraps - https://www.example.com/data?param1=value1¶m2=value2.
I know how to pass a custom parameter from a DynamicLink created in FireBase and get it on my app but the problem is that I can only make this work with the large link version, like this:
https://example.page.link/?link=https://example.com.br/?PARAMETER=VALUE&apn=com.example.br
The problem is that the link is too large, how can I send CUSTOM parameter with the short version from DynamicLink on Firebase?
You can probably get it to work if you send a request body instead of URL parameters. The REST docs explain how to:
{
"dynamicLinkInfo": {
"domainUriPrefix": string,
"link": string,
},
"suffix": {
"option": "SHORT" or "UNGUESSABLE"
}
}
I am using firebase hosting to host few scripts and trying to access them from another site. it naturally gets blocked due to CORS issues. based on my research on other forum threads etc i modified the firebase.json as below
{
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"headers": [ {
"source" : "**",
"headers" : [ {
"key" : "Access-Control-Allow-Origin",
"value" : "*"
} ]
}]
}
}
which essentially allow any url to access the resources hosted here. however, on trying to run my site i still see below
Access to XMLHttpRequest at 'https://oracle-bot-sdk.firebaseapp.com//loader.json'
from origin 'https://insurance-bot.moblize.it' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
what else is needed?
In addition to your firebase.json changes for cors, your firebase functions http / https function needs to also include the cors plugin.
Example
const cors = require('cors')({origin: true});
const functions = require('firebase-functions');
const app = functions.https.onRequest((req, res) => {
cors(req, res, () => {
// Your app stuff here
// Send Response
res.status(200).send(<response data>);
});
});
Express App Example
import express from "express";
const cors = require('cors')({origin: true});
const app = express();
app.get('**', (req, res) => {
cors(req, res, () => {
// Your App Here
// Send response
res.status(200).send(<response data>);
});
});
More documentation Serve Dynamic Content with Cloud Functions - Create an HTTP function to your Hosting site (Cors is not mentioned in the documentation btw)
Is the site (https://insurance-bot.moblize.it/) that is calling to https://oracle-bot-sdk.firebaseapp.com a Firebase hosted app?
I only ask because with version 4.2+ of Firebase Tools allows you to setup Multisite hosting using the same Firebase Project. I am not sure if that would help your situation out at all. Just wanted to mention it.
In the error message:
insurance-bot.moblize.it/:1 Failed to load https://oracle-bot-sdk.firebaseapp.com//loader.json: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://insurance-bot.moblize.it' is therefore not allowed access.
I noticed an extra '/' in https://oracle-bot-sdk.firebaseapp.com//loader.json. I doubt that is the issue, but wanted to mention it.
There is something that you could try. Similar to the answers above but a little different:
"headers": [
{
"source": "*",
"headers": [
{
"key": "Access-Control-Allow-Origin",
"value": "*"
}
]
}
]
Also I would read some of the info here: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Access-Control-Allow-Origin If you have not already.
I hope I was able to help in some way. Let me know.
My guess that you've mixed up firebase hosting and firebase cloud functions. Firebase hosting is made for hosting static websites and web apps. As you try to access from your website that is hosted on different domain your configuration for hosting is not applied. You mentioned that you host some scripts and it sounds like cloud functions. And good old CORS headers can help to your cloud functions like:
exports.corsEnabledFunction = (req, res) => {
res.set("Access-Control-Allow-Origin", "*");
res.set("Access-Control-Allow-Methods", "GET");
res.set("Access-Control-Allow-Headers", "Content-Type");
res.set("Access-Control-Max-Age", "3600");
// Continue with function code
...
}
More info: https://cloud.google.com/functions/docs/writing/http#handling_cors_requests
Make sure you have the Blaze or Flame plan, I think Spark plan blocks external access, maybe for the same reason as it does with cloud functions
Cloud Functions for Firebase - Billing account not configured
Go to the Google Cloud Console: https://console.cloud.google.com/functions/
Click the checkbox next to the function on which you want to grant access.
Click Show Info Panel in the top right corner to show the Permissions tab.
Click Add member.
In the New members field, type allUsers.
Select the role Cloud Functions > Cloud Functions Invoker from the Select a role drop-down menu.
Click Save.
taken from: https://github.com/firebase/firebase-functions/issues/645#issuecomment-605835353
This was the best solution for me as posted above
Go to the Google Cloud Console: https://console.cloud.google.com/functions/
Click the checkbox next to the function on which you want to grant access.
Click Show Info Panel in the top right corner to show the Permissions tab.
Click Add member.
In the New members field, type allUsers.
Select the role Cloud Functions > Cloud Functions Invoker from the Select a role drop-down menu.
Click Save.
taken from: https://github.com/firebase/firebase-functions/issues/645#issuecomment-605835353
Try pasting this as it's directly from the documentation, Customize Hosting Behavior:
"hosting": {
// Add the "headers" section within "hosting".
"headers": [ {
"source" : "**/*.#(eot|otf|ttf|ttc|woff|font.css)",
"headers" : [ {
"key" : "Access-Control-Allow-Origin",
"value" : "*"
} ]
}
}
Firebase hosting CORS doesn't work WITH custom domain.
However, CORS API works with https://yyyyyyy.web.app/ or firebaseapp.com domain
I have been trying to use the api to create service accounts in GCP.
To create a service account I send the following post request:
base_url = f"https://iam.googleapis.com/v1/projects/{project}/serviceAccounts"
auth = f"?access_token={access_token}"
data = {"accountId": name}
# Create a service Account
r = requests.post(base_url + auth, json=data)
this returns a 200 and creates a service account:
Then, this is the code that I use to create the specific roles:
sa = f"{name}#dotmudus-service.iam.gserviceaccount.com"
sa_url = base_url + f'/{sa}:setIamPolicy' + auth
data = {"policy":
{"bindings": [
{
"role": roles,
"members":
[
f"serviceAccount:{sa}"
]
}
]}
}
If roles is set to one of roles/viewer, roles/editor or roles/owner this approach does work.
However, if I want to use, specifically roles/cloudsql.viewer The api tells me that this option is not supported.
Here are the roles.
https://cloud.google.com/iam/docs/understanding-roles
I don't want to give this service account full viewer rights to my project, it's against the principle of least privilege.
How can I set specific roles from the api?
EDIT:
here is the response using the resource manager api: with roles/cloudsql.admin as the role
POST https://cloudresourcemanager.googleapis.com/v1/projects/{project}:setIamPolicy?key={YOUR_API_KEY}
{
"policy": {
"bindings": [
{
"members": [
"serviceAccount:sa#{project}.iam.gserviceaccount.com"
],
"role": "roles/cloudsql.viewer"
}
]
}
}
{
"error": {
"code": 400,
"message": "Request contains an invalid argument.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.cloudresourcemanager.projects.v1beta1.ProjectIamPolicyError",
"type": "SOLO_REQUIRE_TOS_ACCEPTOR",
"role": "roles/owner"
}
]
}
}
With the code provided it appears that you are appending to the first base_url which is not the correct context to modify project roles.
This will try to place the appended path to: https://iam.googleapis.com/v1/projects/{project}/serviceAccount
The POST path for adding roles needs to be: https://cloudresourcemanager.googleapis.com/v1/projects/{project]:setIamPolicy
If you remove /serviceAccounts from the base_url and it should work.
Edited response to add more information due to your edit
OK, I see the issue here, sorry but I had to set up a new project to test this.
cloudresourcemanager.projects.setIamPolicy needs to replace the entire policy. It appears that you can add constraints to what you change but that you have to submit a complete policy in json for the project.
Note that gcloud has a --log-http option that will help you dig through some of these issues. If you run
gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$NAME --role roles/cloudsql.viewer --log-http
It will show you how it pulls the existing existing policy, appends the new role and adds it.
I would recommend using the example code provided here to make these changes if you don't want to use gcloud or the console to add the role to the user as this could impact the entire project.
Hopefully they improve the API for this need.
Is there a way to get an export of the store state / actions programmatically in Production that could be imported back into dev tools?
For example I can setup middleware to capture the current state and send that to something like (Trackjs,Sentry, Rollbar) but that lacks all the previous state and actions.
I would like to capture in the same format as exporting from the Redux Dev Tools.
Sample export from Dev Tools
{"monitorState":{},"actionsById":{"0":{"type":"PERFORM_ACTION","action":{"type":"##INIT"},"timestamp":1471017239656},"1":{"type":"PERFORM_ACTION","action":{"type":"INCREMENT"},"timestamp":1471017242004}},"nextActionId":2,"stagedActionIds":[0,1],"skippedActionIds":[],"committedState":5,"currentStateIndex":1,"computedStates":[{"state":5},{"state":6}]}
This is currently in development but you can now push action history right in the extension see https://github.com/zalmoxisus/remotedev-server/pull/20
Another option is to save the actions to a JSON file as an array and import them back in.
That's possible as of https://github.com/zalmoxisus/redux-devtools-extension/issues/173
logger.js
let actions = []
export function logActions (stateSanitizer) {
return store => next => action => {
actions.push(action)
return next(action)
}
}
These actions can be saved to a file or database and can be imported back into the dev tools.
Sample actions
[{
"type": "INCREMENT"
}, {
"type": "DECREMENT"
}, {
"type": "DECREMENT"
}, {
"type": "DECREMENT"
}, {
"type": "DECREMENT"
}]
I created this repo which demos this in action https://github.com/timarney/redux-trackjs-logger it uses middleware to log the actions when an error happens.
I maintain a Redux middleware called Raven for Redux which attaches Redux data to Sentry error reports. Currently it adds the following context to each error report:
The complete state object.
The complete last action object.
The type of all actions that lead up to the current state. These are added as "breadcrumbs".
The Sentry blog has a writeup describing it in more detail: https://blog.sentry.io/2016/08/24/redux-middleware-error-logging.html
You can find the middleware as an NPM package here: https://github.com/captbaritone/raven-for-redux