Once the Ionic platform is prepared, retrieve from the Angular factory

I have created a firebase Auth factory that looks like this:

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;
  }
]);

The issue I am facing is that when I inject the Auth factory into my ui-router resolve as a dependency, it ends up being empty because the platform ready function runs after the ui-router configuration.

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
          });
        }
      }
    })

I have tried resolving this by altering my factory like so -

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);
          });
      }
    ]);

However, this approach returns a promise which complicates the usage even further.

EDIT : To address this issue, I incorporated promises in the factory

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;
      }
    };
  }
]);

Though this solution works, I am still on the lookout for an improved one.

Answer №1

It's important to understand that you can't simply return an empty object and expect it to transform into the $firebaseAuth instance later on in your code, especially when dealing with asynchronous functions. For more insights on this topic, check out this related question.

// Assigns object A to variable x
var x = {};
// Later assigns an instance of $firebaseAuth() to variable x,
// but only after an empty object {} is initially returned from a function
x = $firebaseAuth(...)

If you need to ensure that certain actions are performed only after the platform is fully ready, remember to chain promises together. This is one of the core benefits of using promises.

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

In your resolve block:

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

For those unfamiliar with Ionic intricacies, it may raise questions as to why Angular is bootstrapped before Ionic is fully prepared. Wouldn't it be better to delay Angular initialization until the platform is completely set up? While I'm unsure about the specifics of implementing this change, it appears to address the core concern (focusing on X over Y).

Answer №2

Don't forget to explore the official Firebase documentation and sample code snippets at

 resolve: {
  // Make sure the controller waits for $waitForAuth to resolve
  // The "Auth" here is a reference to our $firebaseAuth wrapper mentioned earlier
  "currentAuth": ["Auth", function(Auth) {
    // We return a promise from $waitForAuth, allowing the resolve to wait until it's complete
    return Auth.$waitForAuth();
  }]
}

Your Auth factory can be structured like this:

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

This setup avoids any reliance on the ionic platform itself.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing Object Assign to reset the state

Here lies the declaration of my current state: export default new Vuex.Store({ state: { items: [ ], user: { isAuthenticated: false, info: { createdAt: '', email: '', firstName: '&a ...

Challenges with font files in ionic 3 ngx-datatable data table

Hello everyone, I encountered 2 errors when running an ionic 3 app with ngx-datatable: (1) GET http://localhost:8100/build/fonts/data-table.woff net::ERR_ABORTED index.js:5465 (2) GET http://localhost:8100/build/fonts/data-table.ttf net::ERR_ABORTED :81 ...

Incorporating data retrieved through AJAX requests into a Python function

The Flask application described below continuously makes Ajax calls to a backend index function that queries a database and injects the results into a template. However, the injected data is not being refreshed after the Ajax calls are completed, leading ...

Headers with a 3 pixel stroke applied

I have a design on my website that includes a 3px stroke around the header text to maintain consistency. I don't want to use images for this due to issues with maintenance and site overhead. While I know about the text-stroke property, browser suppor ...

I am trying to map through an array fetched from Firebase, but despite the array not being empty, nothing is displaying on the

I retrieved an array of products from a firebase database using the traditional method: export const getUsersProducts = async uid => { const UsersProducts = [] await db.collection('products').where("userID", "==", uid).get().then(sn ...

Tips for preventing directly mutating a prop within a recursive component

The child operates on its own copy of the prop data and can notify the parent using `$emit` when a change occurs. Imagine dealing with a recursive tree structure, like a file system for example: [ { type: 'dir', name: 'music', childr ...

Executing Passport.js for Authentication

I've been trying to understand passport.js by watching tutorials online, but I'm still confused. Can someone clarify my doubts below? Please read the paragraph at the bottom first. If everything is set up correctly, this is how the login strateg ...

Exploring the range of a directive: What you need to know

Here is a link to my code snippet on Plunker that illustrates the issue: http://plnkr.co/edit/bNha1xOrnhnyhvXtXSnX?p=preview angular.module('docsTransclusionExample', []) .controller('Controller', ['$scope', function($scope) ...

An unexpected error occurred: ReferenceError - document is undefined

Error Alert: Unhandled Runtime Error ReferenceError: doc is not defined Source of Issue components\Modal.js (42:18) @ updateDoc 40 | await uploadString(imageRef, selectedFile, "data_url").then(async (snapshot) => { 41 | const do ...

What could be causing the error in Angular Universal Server Side Rendering after deployment on Firebase Hosting?

Currently immersed in Angular development utilizing third-party libraries such as Angular CLI/Angular Universal, following the guidelines laid out here. Also, integrating Firebase hosting and real-time database. The application works flawlessly on my local ...

Issue with retrieving relative time using Moment.js - fromNow()

I want to utilize moment.js to display relative time fromNow(), but I am encountering an issue where the values are being rounded and showing higher durations instead of exact completion times. For example, moment().subtract('s',110).fromNow() / ...

Navigating Redirects using axios in the Browser

Is there a way to work with redirects in axios to capture the redirected URL in the browser when making an API call? I am looking to retrieve the redirected URL through a GET request. ...

Using Node to parse XLSX files and generate JSON data

Hello, I am currently utilizing the js-xlsx package which can be found at this link. My inquiry is how to successfully parse an xlsx file with merges and convert it into JSON format. You can view what the excel sheet looks like here. Ultimately, the JSON o ...

Send a request to templateUrl

After experimenting with AngularJS, I decided to create a dynamic route system that funnels all routes through a single PHP file. This was motivated by my desire to prevent users from accessing raw templateUrl files and seeing unstyled partial pages. Prio ...

Angular 1 Makes Drag and Drop a Breeze

I am exploring a new feature in Angular and trying to create a drag and drop functionality between 2 tables without sorting. Despite no errors in the console, I cannot see any results being displayed. My slight variation in requirements is causing some con ...

Sending data via an AJAX POST request in the request parameter

I have a question regarding the method of making a POST request in my code: $.ajax({ url :"/clientCredentials.json", type: "POST", data: { "clientEmail": email, "clientName":clientName, "orgName":orgName, "l ...

Adjusting the dimensions of the cropper for optimal image cropping

I am currently working on integrating an image cropper component into my project, using the react-cropper package. However, I am facing a challenge in defining a fixed width and height for the cropper box such as "width:200px; height:300px;" impo ...

Encountering the 'data is null' error when making a Twitter API request, yet the data is successfully displayed in the browser

I am attempting to show the number of followers for a Twitter account, but when I connect to the API using this code: $.getJSON("https://api.twitter.com/1/users/show.json?screen_name=uswitchTech&include_entities=true", function(data) { console.log ...

W3C Validation with a Dynamic Twist

I currently have a small feature on my website that indicates the validity of the markup for the current page. It is currently set as "HTML5 Valid", but I am thinking about making it more dynamic. I want it to automatically check if the page's markup ...

Updating a specific field within an array in a Meteor object using MongoDB

I have a document with game details and participants. Here is an example of the structure: { "gameName":"Shooter", "details":[ { "submitted":1415215991387, "author":"XYZ", "subPlayer":{ "members":{ ...