2

Using Polymerfire, I want to add new nodes to a Firebase without overwriting data. (I call this push or put behavior.)

In other words. I want to start with this:

State A
my-app
 |
 - emails
    |
    + email1@example,com
    + email2@example,com

And finish with this.

State B
my-app
 |
 - emails
    |
    + email1@example,com
    + email2@example,com
    + email3@example,com
    + email4@example,com

But when I start with State A and do this:

<firebase-document
    id="doc"
    app-name="app"
    data="{{data}}">
</firebase-document>
...
this.$.doc.save('/', 'emails');

I wind up with this:

State B
my-app
 |
 - emails
    |
    + email3@example,com
    + email4@example,com

Notice the starting data: email1@example,com and email2@example,com were deleted.

Here is the Polymerfire documentation. But it doesn't mention anywhere how to accomplish this type of push or put-type method to insert data into a node.

How can I accomplish this?

Edit

The answer by @motss suggests:

this.$.doc('/emails');

instead of

this.$.doc('/', 'emails');

But that does not work because it adds a random auto key as follows:

State B
my-app
 |
 - emails
    |
    - -hvOxpxwjpWHBYGj-Pzqw
       |
       + email3@example,com
       + email4@example,com

Note the added key: -hvOxpxwjpWHBYGj-Pzqw thereby destroys the indexing feature of the data structure.

Community
  • 1
  • 1
Let Me Tink About It
  • 15,156
  • 21
  • 98
  • 207
  • Far as I know the Firebase has a REST API so you should have a put and post method which can insert items to the node and because the Polymerfire is just wrapping the Firebase javascript you can use the Firebase javascript itself. Docs: https://firebase.google.com/docs/database/web/read-and-write – adaliszk Nov 21 '16 at 06:23
  • @Adamos42: [I see the `update()` method described here](https://firebase.google.com/docs/database/web/read-and-write#update_specific_fields). But there is no mention of it [in the Polymerfire docs](https://elements.polymer-project.org/elements/polymerfire?active=firebase-document). – Let Me Tink About It Nov 21 '16 at 06:43
  • you have the `ref` and the `db` property which should return the `firebase.database().ref()` or the `firebase.database()` instance and after that you able to write your own code. It's sad that we don't have a proper Firabase element which can run any of the firebase api. In my projects I using the Firebase javascript API because it's way more documented than the element. – adaliszk Nov 21 '16 at 06:52

2 Answers2

4

I'm going to assume here that the emails are used as keys for objects and are not an array (since you can't have arrays in a Firebase Realtime Database). If that's the case, you probably want something like:

<firebase-query
  id="emails"
  app-name="my-app"
  path="/emails"
  data="{{emails}}">
</firebase-query>
<script>
  // ...
  this.$.emails.ref.child('email3@example,com').set({new: 'data'});
  // ...
</script>

If you don't want to actually query the emails but just want to insert data, that's easy as well using the JS SDK:

firebase.database().ref('emails').child('email3@example,com').set({new: 'data'});

For a third option, you can use <firebase-document> with a path:

<firebase-document
  app-name="my-app"
  path="/emails/[[emailKey]]"
  data="{{emailData}}">
</firebase-document>
<script>
  // ...
  this.emailKey = 'email3@example,com';
  this.emailData = {new: 'data'};
  // ...
</script>
Let Me Tink About It
  • 15,156
  • 21
  • 98
  • 207
Michael Bleigh
  • 25,334
  • 2
  • 79
  • 85
  • 1
    To anyone using this as an example: Note you have to replace the dot `.` with a comma `,` in the email address. So `email3@example.com` becomes `email3@example,com`. This is the best practice for Firebase because dots are not allowable characters in a Firebase key. And commas are not allowable characters in an email address. (Allowing a unique decode method.) – Let Me Tink About It Nov 22 '16 at 01:22
  • michaelbleigh: I have scoured the docs and made lots of attempts to try to take this to the next level using multiple paths and multiple nodes. But no success. [Could you please take a look at and consider answering this SO question about that](http://stackoverflow.com/q/40749711/1640892)? (You and @FrankvanPuffelen seem to be the world's leading experts on this.) – Let Me Tink About It Nov 22 '16 at 19:08
  • Why don't use `encodeURIComponent` instead of replacing the original data with something else? [encodeURIComponentForFirebase](https://gist.github.com/motss/aae177f7a249db653e00e34214e51038) – motss Nov 24 '16 at 17:05
1

As far as I know, the save method does things differently in two ways:

  1. To set new data into current location.
  2. To push new data into current location.

In order to push new data, you have to submit no key as the second argument in the save method:

// This will push new data into the location /emails.
this.$.doc('/emails');

// To set new data (replacing) at location /emails.
this.$.doc('/', 'emails');

Hope this helps IIRC. Correct me if i'm wrong.

Let Me Tink About It
  • 15,156
  • 21
  • 98
  • 207
motss
  • 662
  • 4
  • 6