2013-07-23 14 views
5

Zmieniono oficjalną dokumentację AngularJS, aby korzystać z Firebase (samouczek dotyczący telefonu).Jak poprawnie wdrożyć angularFireAuth?

Jest to router z mojej aplikacji:

angular.module('phonecat', ['firebase']). 
config(['$routeProvider', function($routeProvider) { 
$routeProvider. 
     when('/phones', { 
     templateUrl: 'partials/phone-list.html', 
     controller: PhoneListCtrl, 
     authRequired: false, 
     pathTo: '/phones' 
     }). 
     when('/phones/:age', { 
     templateUrl: 'partials/phone-detail.html', 
     controller: PhoneDetailCtrl, 
     authRequired: true, 
     pathTo: '/phones/:phoneId' 
     }). 
     when('/login', { 
     templateUrl: 'partials/login.html', 
     controller: LoginCtrl, 
     authRequired: false, 
     pathTo: '/login' 
     }). 
     otherwise({ 
     redirectTo: '/phones' 
     }); }]); 

ten sposób kontroler wygląda - ale prawdopodobnie jest nieprawidłowy. Zostanie wywołana funkcja logowania, ale nie jestem pewien, co robić dalej. Jak mam przekierować użytkownika ze strony logowania na stronę phone-detail.html?

'use strict'; 

function PhoneListCtrl($scope, angularFire, angularFireAuth) { 
    var url = 'https://<link>.firebaseio.com/'; 
    var promise = angularFire(url, $scope, 'phones', []); 
    angularFireAuth.initialize(url, {scope: $scope, name: "user"}); 
} 

function PhoneDetailCtrl($scope, $routeParams, angularFire, angularFireAuth) { 
    var url = 'https://<link>.firebaseio.com/' + $routeParams.age; 
    angularFireAuth.initialize(url, {scope: $scope, path: "/login"}); 
    $scope.$on("angularFireAuth:login", function(evt, user) { 
    var promise = angularFire(url, $scope, 'phone', {}); 
    }); 
    $scope.$on("angularFireAuth:logout", function(evt) { 
    console.log("you are logged out."); 
    }); 
    $scope.$on("angularFireAuth:error", function(evt, err) { 
    console.log(err); 
    }); 
} 

function LoginCtrl($scope, angularFire, angularFireAuth) { 
    var url = 'https://<link>.firebaseio.com'; 
    $scope.form = {}; 
    $scope.login = function() { 
    console.log("called"); 
    var username = $scope.form.username; 
    var password = $scope.form.password; 
    angularFireAuth.login('password', { 
     email: username, 
     password: password, 
     rememberMe: false 
     }); 
    }; 
} 

login.html wygląda następująco:

<input type="text" name="username" ng-model="form.username"><br> 
<input type="text" name="password" ng-model="form.password"><br> 
<button name="login" id="login" ng-click="login()">login</button> 

Co chciałbym osiągnąć to:

  1. Lista wszystkie telefony
  2. Jeśli użytkownik kliknie na uzyskać szczegółowe informacje o jednym z nich, sprawdzić, czy są uwierzytelnione
  3. jeśli tak, pokaż szczegóły telefonu - jeśli nie, przekieruj ich na stronę logowania.
  4. Po zalogowaniu, przekieruj je do widoku szczegółów telefonu.

jestem zmaga się z punktów 3 i 4.

Aktualizacja

Po uwag Anant - Znalazłem coś bardzo ciekawego. Dodałem kilka komunikatów debugowania do angularFire.js i na razie zmieniłem authRequired z true na false w moim kontrolerze powyżej.

Po przejściu do/phones - otrzymuję listę zwróconą z firebase zgodnie z oczekiwaniami. Wewnątrz _loggedIn() dodałem console.log(user) która zwraca obiekt użytkownika (także wewnątrz Inicjalizacja I dodaną oświadczenie debug: https://github.com/firebase/angularFire/blob/master/angularFire.js#L437 - zarówno potwierdzić, że mam ważny użytkownika, już zalogowany

Gdybym następnie kliknij na elemencie, ja. uzyskaj to, czego się spodziewam - nazwa użytkownika i aktualna strona ładują się (zobacz poniższy html). Jeśli odświeżam tę stronę (http: /// phones/#/0), otrzymuję właściwą stronę ponownie i na konsoli wciąż widzę ważny obiekt użytkownika, co oznacza, że ​​użytkownik jest nadal zalogowany

Oto HTML zarówno telefon i telefon-list.html-details.html:

phone-list.html 
<div class="container-fluid"> 
    <div class="row-fluid"> 
     <div class="span4"> 
     <!--Body content--> 

     <ul class="phones"> 
      <li ng-repeat="phone in phones"> 
      <a href="#/phones/{{phone.age}}">{{phone.id}}</a> 
      <p>{{phone.snippet}}</p> 
      </li> 
     </ul> 
     </div> 
    </div> 
    </div> 

phone-detail.html 
<span ng-show="user"> 
    {{user.email}} | <a ng-click="logout()">Logout</a> 
    you are look looking at {{ phone.name }} 
</span> 
<span ng-hide="user"> 
    login pls! 
</span> 

I urywek z JSON (który jest teraz częścią Firebase):

[ 
{ 
    "age": 0, 
    "id": "motorola-xoom-with-wi-fi", 
    "imageUrl": "img/phones/motorola-xoom-with-wi-fi.0.jpg", 
    "name": "Motorola XOOM\u2122 with Wi-Fi", 
    "snippet": "The Next, Next Generation\r\n\r\nExperience the future with Motorola XOOM with Wi-Fi, the world's first tablet powered by Android 3.0 (Honeycomb)." 
}, 
{ 
    "age": 1, 
    "id": "motorola-xoom", 
    "imageUrl": "img/phones/motorola-xoom.0.jpg", 
    "name": "MOTOROLA XOOM\u2122", 
    "snippet": "The Next, Next Generation\n\nExperience the future with MOTOROLA XOOM, the world's first tablet powered by Android 3.0 (Honeycomb)." 
}...etc 

Gdybym wtedy zmienić authRequired powrotem na true - jeśli obiekt użytkownika jest dostępna, a następnie uzyskać nieskończoną pętlę stronie ładuje - najpierw jest to/zaloguj się, a następnie automatycznie przekierowuje/telefon/0 i natychmiast z powrotem do/logowania ponownie, a tak się dzieje, dopóki przeglądarka nie zawiesi się.

Aktualizacja 2

Po dodaniu kilku kolejnych linii debugowania i wywiercenie z kodem Doszedłem z tego rozwiązania:

dodać inicjalizacji do LoginCtrl:

var url = 'https://<link>.firebaseio.com/'; 
angularFireAuth.initialize(url, {scope: $scope}); 

W angularFire.js skomentowałem linie 406 i 407:

//this._redirectTo = null; 
//this._authenticated = false; 

Dołączyłem kod do linii 438, w zasadzie dodałem this._authenticated = true i this._redirectTo = $route.current.pathTo - a także this._authenticated = false do instrukcji else.

var client = new FirebaseSimpleLogin(this._ref, function(err, user) { 
    self._cb(err, user); 
    if (err) { 
     $rootScope.$broadcast("angularFireAuth:error", err); 
    } else if (user) { 
     this._authenticated = true; 
     this._redirectTo = $route.current.pathTo; 
     self._loggedIn(user) 
    } else { 
     this._authenticated = false; 
     self._loggedOut(); 
    } 
    }); 
    this._authClient = client; 
}, 

Jedyny scenariusz, w którym to nie działa jest, gdy użytkownik jest zalogowany i nawigację do http://<host>/#/login - w $route.current.pathTo będzie równa /login i w tej chwili nie jestem w 100% pewien, jak przezwyciężyć to. Jakieś myśli na temat tego Anant?

+0

Hmm, czy to nie przekierowanie do/telefonów /: wiek nie dzieje się zgodnie z oczekiwaniami? Jeśli ustawisz pathTo, pamiętamy go tutaj: https://github.com/firebase/angularFire/blob/master/angularFire.js#L361 i kiedy logowanie się powiedzie, przekierujemy: https://github.com/firebase /angularFire/blob/master/angularFire.js#L498 - Zacznę od wprowadzenia instrukcji debugowania w tych dwóch wierszach. – Anant

+0

Witaj Anant - dziękuję za odpowiedź. Postaram się jeszcze bardziej to rozwikłać i powiedzieć, co wymyśliłem. Moim największym problemem jest to, że nie mogę "zmusić" aplikacji do wyświetlenia strony z danymi teleadresowymi po zalogowaniu. Czy muszę zadzwonić do routera.reload (/ phones /: age)? [Przy okazji, widziałem twoje prezentacje - kontynuuj dobrą pracę z angularFire, uwielbiam to.] – Tamas

+0

Nie musisz wymuszać przeładowania aplikacji, gdy użytkownik zaloguje się pomyślnie, należy wywołać funkcję _loggedIn, która następnie wywołuje $ location.path, aby przekierować aplikację. Wygląda na to, że ta część nie działa, proszę zgłoś problem z Github ze swoimi odkryciami, abyśmy mogli to sprawdzić! – Anant

Odpowiedz

4

Otworzyłem Issue 72 na GitHub: https://github.com/firebase/angularFire/issues/72

Tymczasowy rozwiązanie na razie jest modyfikacja angularFire.js oraz:

Usuń następujące dwa wiersze z funkcji inicjalizacji:

this._redirectTo = null;

this._authenticated = false;

Zmienić angularF ire.js wokół linii 438 (The deklaracja var client), aby przeczytać:

var client = new FirebaseSimpleLogin(this._ref, function(err, user) { 
    self._cb(err, user); 
    if (err) { 
     $rootScope.$broadcast("angularFireAuth:error", err); 
    } else if (user) { 
     this._authenticated = true; 
     this._redirectTo = $route.current.pathTo; 
     self._loggedIn(user) 
    } else { 
     this._authenticated = false; 
     self._loggedOut(); 
    } 
    });` 
    this._authClient = client; 
}, 

Jak wspomniano powyżej, to rozwiązuje prawie wszystko - jedynym problemem wydaje się być to, że jeśli istnieje ważny obiekt użytkownika (tj ktoś jest zalogowany) nawigacja do/login powinna przekierować użytkownika na inną stronę, w tej chwili nic się nie dzieje. Sprawa GitHub powinna mieć dalsze informacje na ten temat, mam nadzieję, że niedługo.