Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: store a list of elements associated with the logged in user in new custom element #11

Open
mm-gmbd opened this issue Jan 22, 2016 · 5 comments
Assignees
Labels

Comments

@mm-gmbd
Copy link

mm-gmbd commented Jan 22, 2016

Hey @MeTaNoV, thanks for these elements - again, these have been a big help. However, I've hit a bit of a snag and I was wondering if you could help me out, and it may even be a nice feature to add to the set of extended elements.

You put together the firebase-auth-manager element, and from there I can easily get the data associated with a particular user. Say, for example, I want to get a list of messages that a particular user has sent, and the list of message IDs are saved under the user tree:

users: {
  $userID: {
    messages: {
      messageID1: true,
      messageID2: true,
      ...
    }
  }
}

Now, here's the complication -- I want to get the contents of each actual message, each of which has an "owner", and provide it in an array or object as a property of a new custom Polymer element:

messages: {
  messageID1: {
    contents: "Hi, I'm a message",
    owner: "userID1"
  },
  messageID2: {
    contents: "Hi, I'm also a message, but I'm not owned by User1",
    owner: "userID2"
  },
  ...
}

So, I've already developed a custom element called x-message-ids that can be used as follows to get the list of message identifiers under a particular user (users/userID1/messages):

<x-message-ids message-ids={{messageIdentifiers}}></x-message-ids>
> {{messageIdenfifiers}} // ["messageID1, "messageID2]

Now, with those message identifiers, I need to perform a query at each message location under /messages to, first, determine if the user is the owner of the message, and, second, get the contents of the messages. I'd like to be able to provide this in an Array that looks like the following:

[{messageID1: "Hi, I'm a message"}] //Notice that messageID2 is not here because it had a different owner

I think one way of going about this could be to combine <x-message-ids> with a <dom-repeat>, and perform a firebase query to each location using <firebase-document>:

<x-message-ids message-ids={{messageIdentifiers}}></x-message-ids>
<template is="dom-repeat" items="[[messageIdentifiers]]" as="messageID">
  <firebase-document log
                     location={{_messageLocation}}
                     data={{contents}}>
  </firebase-document>
</template>

From here, I'm not really sure where to go. Does _messageLocation need to be defined within a <script> tag within the dom-repeat? If so, how do I define an object that all of the firebase-document's have access to, so that, if the query is successful, it can insert its own entry onto?

Thanks in advance, and let me know if I have been unclear or can explain any better.

@mm-gmbd
Copy link
Author

mm-gmbd commented Jan 22, 2016

I guess it would be helpful to include the final objective. Basically, I'd like to be able to, on a page, do something like the following:

<x-messages messages={{messages}}></x-messages>
<template is="dom-repeat" items="[[messages]]" as="message">
  Message contents: {{message}}
</template>

@MeTaNoV MeTaNoV self-assigned this Jan 22, 2016
@mm-gmbd
Copy link
Author

mm-gmbd commented Jan 26, 2016

By the way, I've opened a question on StackOverflow that, if answered, should provide means for this to work.

Also, there's another related question that was answered, but I believe it was for an older version of Polymer and does not work in 1.0.

@mm-gmbd
Copy link
Author

mm-gmbd commented Jan 26, 2016

So, it appears that by using the on-firebase-value listener, a workaround should be possible.

<x-message-ids message-ids={{messageIdentifiers}}></x-message-ids>
<template is="dom-repeat" items="[[messageIdentifiers]]" as="messageID">
  <firebase-document log
                     location={{_messageLocation}}
                     on-firebase-data="_handleFirebaseData">
  </firebase-document>
</template>

...

properties: {
  object: {
    type: Object,
    value: function(){ return{}; },
    notify: true
  }
},

_handleFirebaseData: function(e) {
  //1. extract message identifier (there has got to be a better way of getting this)
  var mID = e.detail.ref().toString();
  mID = mID.splice(...) //do string funkiness to get just the message identifier

  //2. set the property of the object to the value retrieved from Firebase
  this.set('object.'+mID, e.detail.val()); //not even sure if the "." syntax works like this...
}

This is a bad workaround... there has got to be something better, but at least this is kind of progress.

@johnwhitton
Copy link
Contributor

Max,

I'd recommend joining (if you haven't already) https://polymer.slack.com/
to try and chat with people about the issues your facing.
Regarding repeatable elements here are a couple of techniques which may (or
may not) help.
Here https://jsbin.com/lehonit/4/edit?html,console,output is a jsbin that
Arthur Evans provided me (nothing to do with firebase but gives an example
of a dom-repeat.
Below is a code sample using iron-list which I am using to display a
collapsible list of venues modified from the iron-list collapsible demo
https://github.com/PolymerElements/iron-list/blob/master/demo/collapse.html
.
For your messages you may want to look at the simple iron-list
https://elements.polymer-project.org/elements/iron-list?view=demo:demo/index.html&active=iron-list
.
I think the main point is that you may want to look at a collection and
then accessing the individual messages in the array, rather than a document.

Hope this helps.

Regards,

John

Sample Code

Venue Information

<firebase-collection order-by-child="creator" equal-to="[[profileId]]"

location="https://zettafy.firebaseio.com/venues"
data="{{venues}}">



<div class$="[[getClassForItem(venue, venue.expanded)]]"
tabindex="0">


[[venue.name]]

[[venue.address]]




















On Tue, Jan 26, 2016 at 1:00 PM, Max Mueller notifications@github.com
wrote:

So, it appears that by using the on-firebase-value listener, a workaround
should be possible.





...

properties: {
object: {
type: Object,
value: function(){ return{}; },
notify: true
}
},

_handleFirebaseData: function(e) {
//1. extract message identifier (there has got to be a better way of getting this)
var mID = e.detail.ref().toString();
mID = mID.splice(...) //do string funkiness to get just the message identifier

//2. set the property of the object to the value retrieved from Firebase
this.set('object.'+mID, e.detail.val()); //not even sure if the "." syntax works like this...
}

This is a bad workaround... there has got to be something better, but
at least this is kind of progress.


Reply to this email directly or view it on GitHub
#11 (comment)
.

@mm-gmbd
Copy link
Author

mm-gmbd commented Jan 26, 2016

@johnwhitton, thanks for the response. Actually, I had decided to kind of "dumb down" the question by including a <firebase-document> rather than a <firebase-collection>, but in actuality I'm already using a <firebase-collection> in my application.

Thanks for the tip about Slack, I'll head over and see if I can get some further support because I'm starting to lose it >.<

So, I guess just to clarify (although I'll move to Slack soon), I'd like to use a <firebase-collection> inside of a <dom-repeat> and store the contents of the collection in a property of a shared object:

<template is="dom-repeat" items="[[identifiers]]" as="id">
  <firebase-collection
                     location={{_computeIdLocation(id)}} //works just fine
                     data={{_resolveRef(id)}}> //data does not end up at right place
  </firebase-collection>
</template>

...
properties: {
  identifiers: {
    type: Array,
    value: ['identifier1', 'identifier2'] //this list is actually dynamically loaded from Firebase
  },

  allData: {
    type: Object,
    value: function(){return{};}
  },

  allDataWatcher: {
    type: Object,
    compute: '_watchAllData(allData)'
  }
},

_computeIdLocation: function(id){
  return ["https://a-firebase.firebaseio.com/place-to-get-data", id].join('/');
},

_resolveRef: function(id){
  return this.allData[id];
},

_watchAllData(allData) { //This never prints
  console.log("Printing allData");
  console.log(allData);
}

Does that make sense?

I would like the data to look like the following:

allData: {
  identifier1: [{"__firebaseKey__": "a-key", "data": "some_data"}, {"__firebaseKey__": "a-key-2", "data": "other data"}]
  identifier2: [{"__firebaseKey__": "a-key-3", "data": "datadata" }]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants