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:
- Lista wszystkie telefony
- Jeśli użytkownik kliknie na uzyskać szczegółowe informacje o jednym z nich, sprawdzić, czy są uwierzytelnione
- jeśli tak, pokaż szczegóły telefonu - jeśli nie, przekieruj ich na stronę logowania.
- 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?
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
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
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