2016-01-12 1 views
2

J'ai une usine firebase Auth comme suitretour de l'usine angulaire lorsque la plate-forme ionique prêt

app.factory("Auth", ["$firebaseAuth", "FIREBASE_URL","$ionicPlatform", 
    function($firebaseAuth, FIREBASE_URL, $ionicPlatform) { 
     var auth = {}; 
     $ionicPlatform.ready(function(){ 
      var ref = new Firebase(FIREBASE_URL); 
      auth = $firebaseAuth(ref); 
     }); 
     return auth; 
    } 
]); 

J'injectais l'usine Auth dans ma résolution ui-routeur comme la dépendance mais le temps ui-routeur est configuré le auth est vide parce que la plate-forme prête entre en action par la suite.

app.config(function ($stateProvider, $urlRouterProvider) { 
    $stateProvider 
    .state('menu', { 
     url: '/menu', 
     abstract:true, 
     cache: false, 
     controller: 'MenuCtrl', 
     templateUrl: 'templates/menu.html', 
     resolve: { 
     auth: function($state, Auth){ 
      //<--Auth is empty here when the app starts -----> 
      return Auth.$requireAuth().catch(function(){ 
       $state.go('login'); //if not authenticated send back to login 
      }); 
     } 
     } 
    }) 

Comment puis-je m'assurer que l'usine Auth n'est pas vide avant d'être injectée dans le routeur ui?

J'ai essayé -

app.factory("Auth", ["$firebaseAuth", "FIREBASE_URL","$ionicPlatform", 
     function($firebaseAuth, FIREBASE_URL, $ionicPlatform) { 
      return $ionicPlatform.ready(function(){ 
       var ref = new Firebase(FIREBASE_URL); 
       return $firebaseAuth(ref); 
      }); 
     } 
    ]); 

Mais retourne une promesse qui le rend encore plus compliqué à utiliser.

EDIT: je promesses en usine pour résoudre le problème

app.factory("Auth", ["$firebaseAuth", "FIREBASE_URL","$ionicPlatform","$q", 
    function($firebaseAuth, FIREBASE_URL, $ionicPlatform, $q) { 
    var auth = {}; 
    return { 
     getAuth : function(){ 
     var d = $q.defer(); 
     $ionicPlatform.ready().then(function(){ 
      var ref = new Firebase(FIREBASE_URL); 
      auth = $firebaseAuth(ref); 
      d.resolve(auth); 
     }); 
     return d.promise; 
     } 
    }; 
    } 
]); 

Cela fonctionne, mais je cherche une meilleure solution.

+0

Vous semblez retourner un objet vide dans votre usine. – pro

+0

c'est le problème. Je veux retourner de l'usine seulement après la plate-forme prête – Nikhil

Répondre

5

Vous ne pouvez pas renvoyer {}, puis attendre plus tard que cela devienne comme par magie l'instance $firebaseAuth, qui est définie ultérieurement dans une fonction asynchrone. Voir this question pour une formation asynchrone.

// "points" the x variable to object A 
var x = {}; 
// "points" the x variable to an instance of $firebaseAuth() 
// but not before {} is returned from the function 
x = $firebaseAuth(...) 

Si vous voulez attendre que la plate-forme soit prête avant d'exécuter votre fonction de résolution, enchaînez simplement les promesses; c'est à peu près le point des promesses.

app.factory('IonicReady', function($q, $ionicFramework) { 
    return $q(function(resolve, reject) { 
     $ionicPlatform.ready(resolve); 
    }); 
}); 

Et puis dans votre résolution:

resolve: { 
    auth: function($state, Auth, IonicReady){ 
    return IonicReady 
     .then(function() { 
      return Auth.$requireAuth(); 
     }) 
     .catch(function(e) { 
      console.error(e); 
      $state.go('login'); 
     }); 
    } 
} 

Ne pas être un expert ionique, cela pose simplement la question suivante: Pourquoi bootstrap angulaire du tout avant ionique est prêt? Pourquoi Angular n'est-il pas automatiquement amorcé lorsque Ionic est chargé? Il semble plus approprié de ne pas effectuer de routage jusqu'à ce que la plate-forme soit prête à supporter cela et à simplifier le processus depuis la porte. Je ne sais pas comment exécuter cette partie, mais il semble que cela résout le X rather than the Y.

+0

Merci @Kato - J'étais dans le même processus de bootstrapping angulaire après Ionic est prêt - Il a causé des fuites de mémoire et je ne savais pas comment résoudre ce problème. J'utilise des promesses en usine pour résoudre le problème mais je ne suis pas sûr si c'est ainsi que les usines devraient être utilisées ... Voir edit. – Nikhil

0

Assurez-vous de consulter la documentation Firebase officielle et des exemples sur https://www.firebase.com/docs/web/libraries/angular/guide/user-auth.html

resolve: { 
    // controller will not be loaded until $waitForAuth resolves 
    // Auth refers to our $firebaseAuth wrapper in the example above 
    "currentAuth": ["Auth", function(Auth) { 
    // $waitForAuth returns a promise so the resolve waits for it to complete 
    return Auth.$waitForAuth(); 
    }] 
} 

Votre usine Auth peut ressembler à ceci alors

app.factory("Auth", ["$firebaseAuth", 
    function($firebaseAuth) { 
    var ref = new Firebase("https://docs-sandbox.firebaseio.com"); 
    return $firebaseAuth(ref); 
    } 
]); 

sans une dépendance sur la plate-forme ionique lui-même.

+0

Cela ne fonctionne pas parce que vous créez la nouvelle base de données sans l'envelopper avec plate-forme prête. De plus, certaines de mes autres usines ont également le même problème ... par exemple mon usine de message est également injectée en résolution. '' 'app.factory ('Messages', fonction ($ firebaseArray, FIREBASE_URL, $ ionicPlatform) { var entre les utilisateurs = ionique.Plateforme.prêt (function() {var refUserMessages = new (Firebase FIREBASE_URL + "/ UserMessages"); betweenUsers = function (chemin) { retour firebaseArray $ (refUserMessages.child (chemin));} }); retourner entre les utilisateurs; }); '' ' – Nikhil

+0

également, je dois emballer tous les appels liés à la base de feu avec la plate-forme ionique prête. donc $ waitforauth ne résout pas le but – Nikhil

+0

Pourquoi avez-vous besoin d'envelopper tous ces appels dans la fonction prête? Vérifiez par exemple https://www.firebase.com/docs/web/libraries/ionic/guide.html. – gmork