which method will yield better performance? - firebase

Consider an example data structure with nested items. ie: schools.classes.students
In the UI is used to add/edit/delete the students only.
Do I connect the firebase Ref at the root (schools) or classes and get the UI to iterate over and manage the the data or does each student have a dataRef as this is where the data will be changed?
If each student has its own Firebase Ref (lets say 100 students), does this add any performace/latency issues?
I can explain further if needed but wanted to keep post short.

Firebase is intended to be used with large numbers of references and callbacks. Creating a reference ("new Firebase(...)") is an extremely lightweight option, so you should feel comfortable doing this very often.
In your app, usually rendering and network activity are the major bottlenecks, so loading and re-rendering large chunks is likely to be slow. I'd recommend accessing Firebase in a very granular way, and tying it tightly to your GUI so that only the minimum set of GUI elements need to be re-rendered when things change.
If this wasn't clear, please provide some example code and I can make some additional recommendations.
[I work at Firebase]

Related

How to do updates with GraphQL mutations(Hot Chocolate)

We recently introduced GraphQL to our project, I've never used it before, however I like it a lot.
We decided to go with the HotChocolate library for .NET Core and Apollo for client side.
One thing I am not quite sure is about mutations, specifically peforming updates and partial updates with mutations.
I read somewhere that the practice is and that I should stick with creating specific mutation for each update, for instance updateUsername(), updateAddress(), updateCity() all of them should have specific mutation.
Issue with that is that my codebase will grow enormously if I decide to go in that direction, as we are very much data driven, with a lot of tables and columns per table.
Another question is, how to handle nullable properties, I can create a mutation which accepts some input object, but I'll end up with my entity being overwritten and all nullable properties not provided on the calling end will be set to null.
Is there a way to handle this update partially or I should go with specific update mutation for each property I want updated?
I think you understood the best practice around specific mutations wrong. It's less "have one mutation to update one field" and more "have specific mutations that encapsulate actions in your domain". A concrete example would be creating an "addItemToBasket" mutation, instead of having 3 mutations that update the individual tables related to your shopping basket, etc.
GraphQL is very much centered around front-end development, so your mutations should, in general, closely resemble actions a user can perform in your front-end. E.g. your front-end has an "Add to basket" button and your backend has an "addItemToBasket" mutation that resembles the action of placing an item in the user's basket.
If you design your mutations with this in mind, most of the time you shouldn't be having an issue with partial updates, since the mutation knows exactly what's to do and you are not just letting the user of your schema update fields at will.
If for whatever reason you need to have these partial updates, you likely won't get around implementing the patching yourself, unless your data provider supports it. Meaning you will have to have an input object type with nullable properties and your mutation that decides which fields have been changed and changing them using your data provider.
That being said, there's also a proposal for patching types in the Hot Chocolate repository that should simplify the patching part: https://github.com/ChilliCream/hotchocolate/issues/1326
for instance updateUsername(), updateAddress(), updateCity() all of them should have specific mutation.
Issue with that is that my codebase will grow enormously if I decide
to go in that direction, as we are very much data driven, with a lot
of tables and columns per table.
Correct. That's practically impossible to follow that way for more or less big data-driven applications.
Consider how we implement the patching in our API here. Also consider following the discussion about the patching feature in HotChocolate github thread. Hope, that helps!

How to I separate a Web+App into separate web and app projects

I've created a web+app project on Google analytics and it has a lot of data on it I don't want to lose. But... App+Web is not good and makes it ridiculously difficult to see important pieces of data.
How can I separate them into either two separate properties or views?
You cannot separate data that has already been collected into different properties (and views do not even exist in Apps+Web).
If you want to look at App data and Web data separately, you'd have you use filters/segmentation.
Your best chance is to wait until BigQuery integration becomes available and then export the data and write your own aggregations, although that is probably not easier than working with Apps+Web in the first place.
Also this is still a beta, so with enough user feedback they might improve the UI to make data (including already collected data) more easily accessible. But as for short term fixes, there are none.
You can see Technology report: Cross-platform, Web or App.
You can also use Analysis --> Exploration report and create custom reports.

Best practice for managing / controlling object state with 2 way databinding using Polymer

Lets try this explanation again...
I'm new to polymer (and getting back into web dev after a relatively long absence), and I'm wondering what the recommended approach might be to more closely manage object state while employing 2 way databinding. I am currently consuming rest API (json) objects. My question is if polymer keeps a copy of the original object before initiating updates to the bound object's properties/attributes...so one might be able to easily undo the changes? While allowing 2 way databinding to work its magic is often desired, there are cases where I'd like to prevent / delay changes to the object / DOM until the user approves the changes (say via the paper-dialog component for instance). I suppose one could make a temporary copy of the object and bind fields to that version, and then only persist the changes back to the source object upon user approval. In any case, I'd be interested to hear thoughts and see an example or two of recommended approaches (especially if I am off-track with my ideas!)
I suppose one could make a temporary copy of the object and bind
fields to that version, and then only persist the changes back to the
source object upon user approval
This.
Consider that view-models are essentially different from pure data-models (sometimes called business-data). Frequently, the differences are irrelevant and one can use them interchangeably. However, be aware of scenarios where the view-model is distinct (uncommitted user edits are a good example).
The notion of a field editor that requires approval from the user is purely UI/View oriented. Whatever data is managed in that modality is purely in the domain of the view, and fetches/commits to the business-data should be discrete.

Loading a Meteor client app with fake fire-and-forget data

I'm trying to figure out a good way to create tutorials for using Meteor apps. Visually, I've figured out a good approach, and packed this into a smart package:
https://github.com/mizzao/meteor-tutorials.
However, there is a second piece that turns out to be rather hard to figure out.
In many cases, a tutorial app needs to be loaded with fake data, to demonstrate the interface to the user without requiring it to be populated with real data that may be hard to generate. (For example, see https://www.planapple.com/trip/demo/349/ which is a demo for PlanApple). In Meteor, since the content of an app is basically defined by the contents of some collections, I see two ways to do this:
Maintain two sets of collections, one for the tutorial and one for the actual app. Use the first set for the tutorial and the second when the user is actually using the app.
Use one set of collections, and fill it with fake data during the tutorial using a subscription and with real data when the user is actually using the app using a different subscription.
The first approach is clearly bad; it means that one cannot write the app without being agnostic to whether it's being used as a tutorial or not and there is a lot of messy if/else reactive logic in presenting the app that is unnecessary. Moreover, this will be very hard to maintain if the app has more than a few collections.
The second approach seems to be the more Meteor-esque way to do things. What we basically want is for a server publication to fill all the client collections with some fake data, and then allow the data to be manipulated in whatever way on the client side without the changes propagating to the server; the client basically gets a copy of the server's tutorial data and then makes only local changes to it which are then discarded. This boils down to two things:
Sending fake data down from the server to client via a custom subscription into the same named collections as the regular app. This is definitely possible as I've written in https://stackoverflow.com/a/18880927/586086
Ignoring any inserts, updates, and deletes from the client (on the server) after the initial load of data; but allowing them to happen locally. This is also possible if one creates null (unnamed) collections, as in http://docs.meteor.com/#meteor_collection.
The problem is that although it's possible to do each of the two steps above separately, I want to do both of them - I want the data to be loaded into the same named collections as the client would have with real data, to avoid the complicated control logic of having two sets of collections, but I also want changes to be local-only but not propagated back over the subscription during the tutorial.
Anyone have ideas about how to do this?
A related question about whether the second part is possible: How does a Meteor database mutator know if it's being called from a Meteor.method vs. normal code?
EDIT: It seems that what we'd basically want to do in the tutorial is inserting directly against the local Meteor Collection as in {https://stackoverflow.com/a/19523301/586086}. However, is there a way to generally turn on this behavior during the tutorial for all relevant mutators, instead of explicitly having to specify this?
I ended up implementing this myself with the partitioner package, which allows connected clients to be divided up into different slices each containing different data.
Basically, the idea is to put the user(s) into a new partition when they are in the tutorial, and then put them into another partition when they are using the app for real. Works great with the tutorials package as well. This gives up the ability of having changes to be client-local, but storing the tutorial data doesn't have much overhead and turned out to be useful in my case anyway.
An example of an app that does this is https://github.com/mizzao/CrowdMapper.

When not to use a Drupal node?

I've recently created a very simple CRUD table where the user stores some data. For the data, I created a custom node. The functionality works great for creating, editing, and deleting data in the CRUD table using the basic node functionality (I'm actually amazed how fast and easy it was to program the basic functionality with proper access controls using only a tiny bit of code)....
Since the data isn't meant to be treated the same way as 'content' such as a blog post (no title, no body, no commments, no revisions, shouldn't show up on ?q=node page, no previews, no teasers, etc)... I find that I'm spending most of my time 'turning off' and modifying the stuff that drupal does automatically for nodes.
I know its a matter of taste, but where should one draw the line on what should be treated as a node and what shouldn't? In other words, would it be better to program this stuff from scratch without using nodes?
Using nodes for custom data has quite some additional benefits besides easy edit/update/delete functionality:
possible categorization via taxonomy
implicit 'ownership' via author tracking
implicit tracking of creation/modification time
basic access control by default, expandable by a huge selection of modules
flexible query generation/listing/filtering via views
possible ad hoc extensions/annotations via CCK fields
possible definition of workflows, actions and the like
a huge number of hooks to programmatically intercept/adjust almost every usage aspect/scenario
commenting, voting, rating and tons of other functionality provided by all contributed modules that work on/with nodes ...
Given all this, I'd say you need a very good reason to not use nodes to store data in Drupal. Nodes are simply the fundamental building blocks for just about everything in the Drupal ecosystem, and the overhead of removing some unwanted default 'features' seems pretty small in comparison to the gains.
That said, one possible reason/argument to handle data separate from the node system might be if that data is directly aimed at annotating other nodes (think taxonomy). But since you can easily reference nodes from other nodes (with lots of different options on how to do this), the argument is not to strong.
Another (much stronger) argument would be data integrity - Drupal is not very strong (to put it politely) concerning normalized, relational data storage, referential integrity, transaction handling and other related topics. If you have requirements in that direction, you might have no choice but to skip the node concept and create and maintain a separate data island within the system on your own.
It helps to think also that a node doesn't need to be public either. Some nodes are private/internal and can be controlled further with access controls. The way you are doing it, whatever you're doing, makes all the scalability and extending it on your shoulders.
I would probably approach it with CCK/Taxonomy depending on what I was doing. That way, I get the added benefit of Views/Panels/etc module integration without writing any additional code.

Resources