Polymer 1.x + Firebase 2.x: данные Firebase не загружаются при первом рендеринге после входа в систему

При первой загрузке страницы после входа пользователя в систему я хочу заполнить свойство items набором объектов, хранящихся в моей Firebase.

A достигает желаемого поведения.

A
<firebase-query
    id="query"
    ...
    path="users/[[user.uid]]/widgets"
    data="{{items}}">
</firebase-query>

B нет.

B
<firebase-query
    id="query"
    ...
    path="widgets"
    data="{{items}}">
</firebase-query>

При использовании B я ожидаю увидеть заполнение объекта items, но вместо этого объект items имеет значение null. Однако, если я обновлю браузер вручную (без выхода из системы), элемент будет вести себя так, как ожидалось. Однако, если я выйду из системы (затем обновлю в то время как вышел из системы), проблема появится снова, пока я не перезагружусь снова. Если я только выйду из системы, а затем снова войду, проблема не появится снова из-за, я думаю, частично того факта, что приложение не сбросить, как описано здесь.

Почему A работает? Но не B? И какие изменения нужно внести в B, чтобы он заработал? (Потому что я хочу сохранить widgets из пути root/widgets/ и не хранить эту информацию в пути users/....

Предыдущие неудачные попытки

Моя текущая (недоказанная) теория состоит в том, что в случае B (когда URL-адрес постоянный/статический, т. е. widgets/) firebase-query участвует в каком-то состоянии гонки. ; и извлекает данные только после некоторого события жизненного цикла и не пытается повторно извлечь данные. С другой стороны, firebase-query делает попытку повторной выборки, когда путь динамически обновляется на основе привязки данных в атрибуте path (т. е. path="users/[[user.uid]]/widgets"). Верна ли эта теория? Или есть какая-то другая причина? Нужно ли мне обязательно извлекать данные после какого-то события? Если да, то как я могу выполнить все это?

Я пробовал следующие идеи без успеха.

C
user: {
  type: Object,
  notify: true,
  observer: '_userChanged',
},

_userChanged: function() {
  this.$.query.path = 'widgets';
  var items = this.$.query.ref.child('widgets');
  this.set('items', items);
},
D
<firebase-query
    id="query"
    ...
    path="[[path]]"
    data="{{items}}">
</firebase-query>

<script>
...
  properties: {
    path: {
      type: String,
      value: function() {
        return 'widgets';
      },
    }
  },
...
</script>

Кроме того, на сайте Polymer Slack @will-in-china говорит:

У меня были проблемы с загрузкой данных в первый раз, я обнаружил, что если у меня нет более одной ссылки на один и тот же путь, я не получаю эту проблему.

Я не уверен, что это означает в данном контексте, поскольку у меня есть только одна ссылка в моем элементе (и приложении) на путь path="widgets" внутри элемента firebase-query.


person Let Me Tink About It    schedule 04.12.2016    source источник
comment
Вы исключили проблемы с локальным хостом, связанные с http/cache при выборке? я не думаю, что это было бы так, но, по крайней мере, отложите в сторону стандартную проблему проверки конфигурации вашего браузера, чтобы кэширование не добавляло дополнительных проблем.   -  person Robert Rowntree    schedule 04.12.2016
comment
есть ли какой-либо код XHR, связанный с Fetch? Я говорю это, потому что я думаю, что в коде шаблона вы можете вручную запустить/повторно запустить Fetch для [[items]] вместо того, чтобы полагаться на документированные наблюдатели жизненного цикла на связанных объектах?   -  person Robert Rowntree    schedule 04.12.2016
comment
@RobertRowntree: Уберите мой предыдущий комментарий. Я еще не нашел решения. Я только думал, что сделал. Нет, код XHR не связан с выборкой. Не могли бы вы объяснить свою идею во втором комментарии? И как я могу исключить проблемы с локальным хостом? Я имею в виду, я очистил кеш, но что еще я могу сделать, кроме этого? Проблема все еще сохраняется.   -  person Let Me Tink About It    schedule 04.12.2016
comment
Вы можете перейти на «slack» по адресу: polymer-slack.herokuapp.com   -  person Robert Rowntree    schedule 04.12.2016


Ответы (3)


я не думаю, что это ваша конкретная проблема, но она может быть похожа на то, что после входа в систему -> setNewRoute(nextPage) я не получил рендеринг и изменил последующий шаблон ( Iron-Ajax ), чтобы он запускался вручную, а не через наблюдателя.

  loggon: function parseLogin(user, password) {
...

     Parse.User.logIn(_user, _pass).then(function() {
      page('/channels');

---
channels.render ...

      _render: function() {
        console.log('_render');
        this.$.get_channlinq.headers = hdr;
        //xhr params
        var body = this._setQry(this.params.channelId);
        this.$.get_channlinq.body = JSON.stringify(body);
        //fetch , load , template will render
        this.$.get_channlinq.generateRequest(); 
person Robert Rowntree    schedule 04.12.2016

«При использовании A я ожидаю, что объект элементов будет заполнен, но вместо этого объект элементов будет нулевым. Однако, если я обновлю браузер вручную (без выхода из системы), элемент будет вести себя так, как ожидалось. Однако, если я выйду из системы (затем обновлю при выходе из системы) проблема появляется снова, пока я снова не перезагружу».

Я вижу подобное поведение в своем приложении. В моем случае это связано с условиями гонки firebase-auth и firebase-query. В моем случае,

  1. #P3# <блочная цитата> #P4#
  2. Когда я обновляюсь после входа в систему, поскольку я уже аутентифицирован, запрос выполняется успешно.

Чтобы отладить эту проблему, я добавил обработчик ошибок для вывода разрешений. Чтобы обойти эту проблему, я использую свойство disabled. При первой загрузке страницы все запросы отключены. Только когда аутентификация прошла успешно, я переключаю «отключено», после чего запросы срабатывают успешно.

signIn: function(){
  var email = this.user.email;
  var password = this.user.password;
  this.$.auth.signInWithEmailAndPassword(email, password)
     .then(function(response){
		self.disabled = false;
		// console.log('signin', response);
	 })
	.catch(function(error){
		console.log('auth-element:signIn error is', error.detail);
	 })
	.then(function(){
	   // call other functions
	});
 },
handleError: function(error){
  console.log('error message', error.detail.message);
},
<firebase-query
   id = "query"
   app-name="my-app"
   path = "/shoeboxes"
   data = "{{datauid}}"
   on-error="handleError"
   disabled="{{disabled}}">
</firebase-query>

Надеюсь это поможет. По сути, я обнаружил, что с полимером и огнеупорной базой обещания лучше, чем автоматические привязки...

person Suprada    schedule 09.12.2016

Я опаздываю, но я разрешаю это с помощью условия dom-if, если пользователь не может сделать запрос, если пользователь не аутентифицируется

person Neiro    schedule 23.03.2017