6

すべてのコントローラーで「現在のユーザー ID」を利用できる確実な方法を探しています。使用: Firebase シンプルログイン: メール/パスワード認証

私の ida: 「現在のユーザー ID」を常に利用できるようにするには、コントローラーに挿入できる「ファクトリ」が必要です。

私はこのコードを思いつきました:

    app.factory('User', ['angularFire',

    //Get Current UserID

    function(angularFire){

        console.log ('FACTORY: User');
            var currentUser = {};
            var ReturnStr = '';
        var ref = new Firebase("https://myFIREBASE.firebaseio.com/");
        var authClient = new FirebaseAuthClient(ref, function (err, user) {

            if (err) {
                    ReturnStr = 'FACTORY: User Error: ' + err; 
                console.log (ReturnStr);
                        //var User = ReturnStr;
            } else if (user) {
                console.log ('FACTORY: User: Login successfully:');
                console.log (user);
                currentUser = user;
            } else {
                //console.log ('-----------User: Logged Out ---------------');
                    ReturnStr = 'FACTORY: Logged out: Redirect to Login'; 
                console.log (ReturnStr);
                window.location.href = "/login.php";
            }
        });

    return currentUser;
        }
]);

私の最も単純なコントローラーは次のようになります。

function ToDoCtrl($scope, User) {
    $scope.MyUser = User;
    $scope.MyUser.test = 'Test';
}

HTML(角度部分)には次のものがあります:

<h2>{{MyUser.id}}</h2>
<h2>{{MyUser.email}}</h2>
<h2>{{MyUser.provider}}</h2>
<h2>{{MyUser.test}}</h2>

=> ID、電子メール、プロバイダーは「未定義」です。コンソールに「FACTORY: User: Login successfully:」と表示され、正しいユーザー - オブジェクトが表示されます。

=> データの問題の非同期ロード?

私も実験しました(運が悪い):

        $timeout(function () {
        currentUser = user;
        }

このような FACTORY は非常に便利です。私を正しい方向に向けてくれてありがとう!

編集 1.1: 今、$rootscope ハックで

=> 同じ効果 - mycontroller が速すぎる - 工場出荷時から遅い。

app.factory('User', ['$rootScope', '$timeout', 'angularFire',

    //Aktueller Benutzer auslesen

    function($rootScope, $timeout, angularFire){

        console.log ('FACTORY: User');
            var currentUser = {};
            var ReturnStr = '';
        var ref = new Firebase("https://openpsychotherapy.firebaseio.com/");
        var authClient = new FirebaseAuthClient(ref, function (err, user) {

            if (err) {
                    ReturnStr = 'FACTORY: User Error: ' + err; 
                console.log (ReturnStr);
                        //var User = ReturnStr;
            } else if (user) {
                console.log ('FACTORY: User: Login successfully:');
                        //currentUser = user;

            $timeout(function () {
                        ReturnStr = 'FACTORY: Inside timout'; 
                  console.log (ReturnStr);

                            currentUser = user;
                  console.log (currentUser);

                $rootScope.myUser = user;
                $rootScope.myUserID = user.id;
                $rootScope.loggedIn = true;
                            $rootScope.$apply();

                  return currentUser;
            });


            } else {
                //console.log ('-----------User: Logged Out ---------------');
                    ReturnStr = 'FACTORY: Logged out: Redirect to Login'; 
                console.log (ReturnStr);
                        //var User = ReturnStr;
                window.location.href = "/login.php";
            }
        });

    return currentUser;
        }
]);

役立つ提案があればTAHNKS!他の人がこれをどのように解決するのか疑問に思います!

4

4 に答える 4

14

したがって、これがこの正確な問題に対する私の解決策です。Angular アプリに Firebase、FirebaseAuthClient、angularFire を使用しています。$scope をファクトリに挿入できないログイン システムでも同じ状況に遭遇したため、取得、追加、更新、および削除のメソッドにファクトリを使用するコントローラを作成することにしました。コントローラーでは、firebaseAuth の処理、User 値の設定、およびそのスコープに割り当てる参照を行います。ユーザーがログインすると、別の場所にリダイレクトされます。その時点で、app.js ファイルは、そのアドレスの場所にある子コントローラーを引き継ぎます。

私のログインも localStorage を使用しているため、ログインは持続し、更新してログインし続ける必要はありません。Cookie または sessionStorage に簡単に変更できます。

このメソッドを使用することを選択した場合、これは特にニーズに合わせて調整する必要があります。それは非常に複雑ですが、これは私にとって非常に堅実であり、firebaseAuth や angularFire について心配する必要はもうありません。私の工場はすべて、データをやり取りするように設定されています。私はAngularJSのことを主にディレクティブでやっています。だからここに私のコードがあります。

注:これは変更する必要があり、必要に応じて把握するために、疑似または制限のないものもあります。

AuthCtrl.js

'use strict';

angular.module('YOUR_APP', []).
controller('AuthCtrl', [
'$scope',
'$location',
'angularFire',
'fireFactory',

function AuthCtrl($scope, $location, angularFire, fireFactory) {
    // FirebaseAuth callback
    $scope.authCallback = function(error, user) {
        if (error) {
            console.log('error: ', error.code);
            /*if (error.code === 'EXPIRED_TOKEN') {
                $location.path('/');
            }*/
        } else if (user) {
            console.log('Logged In', $scope);
            // Store the auth token
            localStorage.setItem('token', user.firebaseAuthToken);
            $scope.isLoggedIn = true;

            $scope.userId = user.id;

            // Set the userRef and add user child refs once
            $scope.userRef = fireFactory.firebaseRef('users').child(user.id);
            $scope.userRef.once('value', function(data) {
                // Set the userRef children if this is first login
                var val = data.val();
                var info = {
                    userId: user.id,
                    name: user.name
                };
                // Use snapshot value if not first login
                if (val) {
                    info = val;
                }
                $scope.userRef.set(info); // set user child data once
            });

            $location.path('/user/' + $scope.userRef.name());
        } else {
            localStorage.clear();
            $scope.isLoggedIn = false;
            $location.path('/');
        }
    };

    var authClient = new FirebaseAuthClient(fireFactory.firebaseRef('users'), $scope.authCallback);

    $scope.login = function(provider) {
        $scope.token = localStorage.getItem('token');
        var options = {
            'rememberMe': true
        };
        provider = 'twitter';

        if ($scope.token) {
            console.log('login with token', $scope.token);
            fireFactory.firebaseRef('users').auth($scope.token, $scope.authCallback);
        } else {
            console.log('login with authClient');
            authClient.login(provider, options);
        }
    };

    $scope.logout = function() {
        localStorage.clear();
        authClient.logout();
        $location.path('/');
    };
}

]);

そして今、素敵でシンプルですが、かなり再利用可能なファクトリです。baseUrl 変数を機能させるには、アプリの Firebase パスを設定する必要があります。

fireFactory.js

'use strict';
angular.module('YOUR_APP').
factory('fireFactory', [
function fireFactory() {
    return {
        firebaseRef: function(path) {
            var baseUrl = 'https://YOUR_FIREBASE_PATH.firebaseio.com';
            path = (path !== '') ?  baseUrl + '/' + path : baseUrl;
            return new Firebase(path);
        }
    };
}

]);

情報

ユーザーデータを保存する場所へのフルパス参照の一部として使用される「users」などのパス参照の一部をファクトリに指定します。

fireFactory.firebaseRef('users')

ユーザーの参照セットを取得したら、再度設定する必要はありません。既存のデータと .auth() を使用するだけです。さらに、localStorage に既存の「トークン」がある場合は、それを使用してユーザーも auth() します。

それ以外の場合は、ユーザーを login() し、指定したオプションを使用して Oauth ウィンドウを開きます。

Firebase/FirebaseAuthClient と angularFire に関しては、これよりも優れたものを探して、何日も何時間も何ヶ月も費やしてきました。Firebase API と FireAuth API のやり方では、とにかく angularFire でそれらを使用するときに、それらをうまく連携させるのは非常に面倒です。とてもイライラしますが、ようやく乗り越えました。

私のアプリのコードをチェックアウトして、これらのことをより完全に行う方法を確認したい場合は、Webernote github リポジトリのこのブランチで見つけることができます。

フォークしたり、ローカルにインストールして実行したり、必要に応じて貢献したりしてください。私は自分でいくつかの助けを使うことができました:)

これがお役に立てば幸いです!!

于 2013-06-24T09:09:10.653 に答える
0

私のために働く別の解決策:

account.service.js

(function() {
    'use strict';

    angular
        .module('app.account')
        .factory('Account', Account);

    Account.$inject = [
        '$firebaseAuth',
        '$firebaseObject'
    ];

    /* @ngInject */
    function Account(
        $firebaseAuth,
        $firebaseObject,
    ) {
        var firebaseRef = new Firebase('https://<<-- MY_FIREBASE -->>.firebaseio.com');
        var authObj = $firebaseAuth(firebaseRef);
        var service = {
            userInfo: null
        };
        activate();
        return service;

        ////////////////

        function activate() {
            // Add listeners for authentication state changes
            authObj.$onAuth(function(authData) {
                if (authData) {
                    // Load the userInfo
                    loadUserInfo(authData);
                } else {
                    // Destroy the userInfo Object if one exists
                    if (service.userInfo) {
                        service.userInfo.$destroy();
                        service.userInfo = null;
                    }
                }
            });
        }

        function loadUserInfo(authData) {
            var userRef = firebaseRef.child('users').child(authData.uid);
            var loadedInfo = $firebaseObject(userRef);

            loadedInfo.$loaded()
            .then(function() {
                service.userInfo = loadedInfo;
            })
            .catch(function(error) {
                switch (error.code) {
                    case 'PERMISSION_DENIED':
                        alert('You don\'t have the permission to see that data.');
                        break;
                    default:
                        alert('Couldn\'t load the user info.');
                }
            });
        }
    }
})();

some-component.controller.js

(function() {
    'use strict';

    angular
        .module('app')
        .controller('SomeController', SomeController);

    SomeController.$inject = [
        'Account'
    ];

    /* @ngInject */
    function SomeController(
        Account
    ) {
        var vm = this;

        vm.userInfo     = userInfo;

        ////////////////

        function userInfo() {
            return Account.userInfo;
        }

        ...
    }
})();

some-component.html

...
<div class="user-id">
    {{vm.userInfo().id}}
<div>
...
于 2015-10-13T21:46:23.170 に答える