Setting up the Polymer with Firebase for production - firebase

I am using Polymerfire library and a native javascript API in my project and I need to set up the production environment. I searched through multiple posts (for example this one) and I came to a conclusion that I need to create a separate project. However since I am using Polymerfire library I have my app name specified all over the project.
<firebase-auth id="auth" user="{{user}}" app-name="project-name" provider="password"
signed-in="{{signedIn}}"></firebase-auth>
To deploy in production it is required to change this name everywhere. I was thinking that I could create a computeAppName function which would return the app name according to the environment but I hope there is a better solution.
The same issue doesn't occur when I use the native javascript API because I am simply selecting the first app in the array (I'll never use multiple apps in my project).
Example
var actionCode = this.route.__queryParams["oobCode"],
auth = firebase.apps[0].auth();
In my opinion ideal, behavior would be if Polymerfire library automatically selected the only existing app in firebase.apps array. If that would be the case I could initialize one firebase-app element with app name in index.html and leave the app name unspecified deeper in the DOM tree.
This issue would be eliminated if I stopped using the Polymerfire library entirely but that would not follow the "Polymer way" of doing things.
Another option would be to create a task in a build system (like gulp) to replace the app name for production but that would be probably overly complicated.
What do you think?
Edit:
For now I am using a workaround:
firebase-app element in index.html:
<firebase-app id="main_app"
name="project-id"
api-key="key"
auth-domain="project-id.firebaseapp.com"
database-url="https://project-id.firebaseio.com"
storage-bucket="project-id.appspot.com">
</firebase-app>
In every element where Polymerfire is used I created a appName property which uses document selector to get the app name from element in the index:
appName: {
type: String,
value: function () {
return document.getElementById("main_app").name;
}
}
<firebase-auth id="auth" user="{{user}}" app-name="[[appName]]" provider="password"
signed-in="{{signedIn}}"></firebase-auth>
Thanks Jan

Name property of firebase-app element is only used as a name for the firebase app object, which can be arbitrary and there is no need to change it when switching to production project.

Related

How to use API resources in Laravel Inertia?

I am using Laravel 9, Jetstream, Inertia, Vue 3.
I have created an Api Resource for my Model Project
$projects = ProjectResource::collection(Project::get());
return Inertia::render('Project/Edit', compact('projects'));
In Vue, in the props "project" i get a nested array "data" and only the objects I need are already in it.
projects: Reactive
data:Array[2]
0:Object
1:Object
And it should be like this
projects:Reactive
0:Object
1:Object
I don't want to access props in vue via "projects.data"
I want it to be: "projects"
How to achieve this?
Taken from the official laravel docs (Data Wrapping)
By default, your outermost resource is wrapped in a data key when the resource response is converted to JSON.
In order to turn off this behaviour:
If you would like to disable the wrapping of the outermost resource, you should invoke the withoutWrapping method on the base Illuminate\Http\Resources\Json\JsonResource class.
So basically you need to run:
JsonResource::withoutWrapping();
In the boot method of your AppServiceProvider.

How to make AWS Api Gateway deployment depend on dynamic list using Terraform

When I generate resources, methods etc. using "for_each", how can I make a deployment depend on them? Terraform requires a static list as value for "depends_on"
I think what you are looking for here is this (somewhat hidden) reference in terraform documents about triggers
I was facing the same issue (using for_each to create gateway methods, integrations) but was not able to reliably trigger api-gateway redeployment, until this...
... or removing the .id references to calculate a hash against whole resources. Be aware that using whole resources will show a difference after the initial implementation. It will stabilize to only change when resources change afterwards
This allow us to do the following in triggers
triggers = {
redeployment = sha1(jsonencode([
aws_api_gateway_resource.gateway_resources,
aws_api_gateway_method.gateway_methods,
aws_api_gateway_integration.gateway_integrations,
]))}
By removing .id (and thus not needing to reference each.key, or any element in the dynamic list) you let terraform decide if the hash of the file changed. If it did it will redeploy, if it doesnt change, then no redeploy required :)
Reference https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_deployment#terraform-resources
Look at the comments on 'triggers'

How do you manage adding new attributes on existing objects when using firebase?

I have an app using React + Redux and coupled with Firebase for the backend.
Often times, I will want to add some new attributes to existing objects.
When doing so, existing objects won't get the attribute until they're modified with the new version of the app that handles those new attributes.
For example, let's say I have a /categories/ node, in there I've got objects such as this :
{
name: "Medical"
}
Now let's say I want to add an icon field with a default of "
Is it possible to update all categories at once so that field always exists with the default value?
Or do you handle this in the client code?
Right now I'm always testing the values to see if they're here or not, but it doesn't seem like a very good way to go about it. I'd like to have one place to define defaults.
It seems like having classes for each object type would be interesting but I'm not sure how to go about this in Redux.
Do you just use the reducer to turn all categories into class instances when you fetch them for example? I'm worried this would be heavy performance wise.
Any write operation to the Firebase Database requires that you know the exact path to the node that you're writing.
There is no built-in operation to bulk update nodes with a path that is only partially known.
You can either keep your client-side code robust enough to handle the missing properties, or you can indeed run a migration script to add the new property to each relevant node. But since that script will have to know the exact path of each node to write, it will likely first have to read/query the database to determine those paths. Depending on the number of items to update, it could possibly use multi-location updates after that to update multiple nodes in one call. E.g.
firebase.database().ref("categories").update({
"idOfMedicalCategory/icon": "newIconForMedical",
"idOfCommercialCategory/icon": "newIconForCommercial"
"idOfTechCategory/icon": "newIconForTech"
})

Passing value between two components in angular2-meteor project

I am using angular2-meteor.
When I try to pass a value between two components (when the value change in the first component, create an event in second component and use this new value), I have two ways right now:
One way is meteor way: using this.autorun and Session.get.
Another way is angular2 way: using Injectable service with EventEmitter.
Which way should be prior? Or is there any other better way? Thanks
Now I used angular2-meteor a while.
Although the angular2-meteor tutorial has no example so far about using or choosing Angular 2 service or Meteor Session.
But I feel angular 2 takes the lead in the front end, while meteor makes reactivity easier and also handle all back end things.
So I went with angular2 way using service to share between components. And service is very powerful like #todd-w-crone said.
If anyone has better answer, I will switch to accept that one.
I find it practical to create a new service called App.states.ts which is accessed globally and mimics Session (get / set).
I commonly import this service to all necessary components to get or set new value such as User.status, company.profile, lastProduct, etc.
Since this service is #injectable it can also make use of other services, in case a value hasn't been set already.
This allows me to ask for a variable in a component appState.getLastModifiedItem(), then in app.states.ts I'll write this function to pass this.modifiedItem or either:
Request another service item.service.ts to fetch data
Call another function with itemCollection.findOne({...}) and return such value.
You can configure Mongo queries as you want and either store static data in appState or keep subscription items in appState.
Do take into consideration that all subscriptions handled by an #injectable within a component are imported by such component. Be wary of conflicting subscriptions between components/services.

Accessing other templates' instances

You can access the current template's instance by doing Template.instance(). But you often run into situations where you have to access other templates' instances as well. For example, if you use ReactiveVar, then you would want to get or set variables that are attached to other template instances.
I came across How to get the parent template instance (of the current template) but this is not complete.
Q1. How can we access any template's instance, not just the current template's
Q2. Is it against the Meteor way if I need to access other templates' instances?
you can try to set your template variable directly at the template level instead of inside the instance.
Template.example.myVariable = new ReactiveVar();
instead of
Template.example.onCreated(function (){
this.myVariable = new ReactiveVar();
});
The closest I got was to target the template by one of its elements (assume the template contains a form)
Blaze.getView($('form')[0]).templateInstance().someReactiveVar.set('changed')
If your target templates are in the same file, you can just define the reactive variable outside the template functions, at the beginning of the file. All templates in the file will access it.
If your target template is the parent template, (or any further parent template) you can access its data context using Template.parentData() the argument being the rank of the parent (default is 1). It seems that you know that already.
If you need to access a DOM element within a different template in the same page, you can use jQuery selectors.
I don't know any other way to reach another template instance (afaik, there is no Blaze.getTemplate(name) function.) The answer you are referring to seems to be the better you can get.
I think this is purely subjective, since in Meteor there are so many different ways of doing things, but I actually think Session is perfectly suited for sharing variables across several templates. People argue that Session is bad since it's global and can pollute the namespace. I would argue that it's up to the developer to keep their environment clean in any way that works for them. So for instance, this is bad:
Session.set('count', 23);
Session.set('last', new Date());
But this is better:
Session.set('notifications/count', 23);
Session.set('notificatinos/last', new Date());

Resources