0

Disambiguation:

This issue is not because rewrites have somehow been misconfigured in the firebase.json. The Firebase docs clearly state how to do this here. The problem is that only shallow links work; deep links do not.

Problem:

Deep links do not work after turning on html5Mode using AngularFire with Firebase: First level pages load; any other page will not. So /login works but /supplier/accounts does not.

config.js:

function configState($stateProvider, $urlRouterProvider, $compileProvider, $httpProvider) {
    // Optimize load start with remove binding information inside the DOM element
    $compileProvider.debugInfoEnabled(true);

    // Set default state
    $urlRouterProvider.otherwise("/login");

    $stateProvider
        /* 
         * Common Views
         */
        .state('common', {
            abstract: true,
            templateUrl: "views/common/content_empty.html",
            data: {
                pageTitle: 'Common'
            }
        })
        .state('common.login', {
            url: "/login",
            templateUrl: "views/common_app/login.html",
            data: {
                pageTitle: 'Login page',
                specialClass: 'blank'
            }
        })
        .state('common.logout', {
            url: "/logout",
            templateUrl: "views/common_app/logout.html",
            data: {
                pageTitle: 'Logout page',
                specialClass: 'blank'
            },
            resolve: {
                // controller will not be loaded until $requireAuth resolves
                "currentAuth": ["$state", "Auth", "loginRedirectPath", function($state, Auth, loginRedirectPath) {
                    return Auth.$requireAuth();
                }]
            }
        })

        /* 
         * Secure Abstract Class
         */
        .state('secure', {
            abstract: true,
            templateUrl: "views/common/content_empty.html",
            resolve: {
                // controller will not be loaded until $requireAuth resolves
                "currentAuth": ["$state", "Auth", "loginRedirectPath", function($state, Auth, loginRedirectPath) {
                    return Auth.$requireAuth();
                }]
            }
        })   


        /* 
         * Supplier Accounts
         */
        .state('secure.account', {
            abstract: true,
            url: "/supplier",
            templateUrl: "views/common/content.html",
            data: {
                pageTitle: 'Supplier'
            }
        })       
        .state('secure.account.accounts', {
            url: "/accounts",
            templateUrl: "views/account/accounts.html",
            controller: "suppliersListCtrl as suppliersListCtrl",
            data: {
                pageTitle: 'Accounts',
                pageDesc: 'Accounts assiged to this User'
            }
        })
};

angular
    .module('app')
    // for ui-router
    .run(["$rootScope", "$state", function($rootScope, $state) {
        $rootScope.$on("$stateChangeError", function(event, toState, toParams, fromState, fromParams, error) {
            // Catch the error thrown when the $requireAuth promise is rejected
            // redirect the user back to the login page
            if (error === "AUTH_REQUIRED") {
                console.log("AUTH_REQUIRED Fired!!!");
                $state.go("common.login");
            }
        });

        // Log ui-router errors in the console
        $rootScope.$on("$stateChangeError", console.log.bind(console));
    }])
    .factory("Auth", ["$firebaseAuth", "FIREBASE_URI",
        function($firebaseAuth, FIREBASE_URI) {
            var ref = new Firebase(FIREBASE_URI);
            return $firebaseAuth(ref);
        }
    ])
    .config(["$locationProvider", function($locationProvider) {
        $locationProvider.html5Mode(
            {
                enabled: true,
                requireBase: false
            });
    }])
    .constant('FIREBASE_URI', '<FIRE BASE URI HERE>')
    .constant('loginRedirectPath', 'common.login')
    .config(configState)

firebase.json:

{
    "firebase": "firebase-app",
    "public": "main",
    "rewrites": [{
        "source": "**",
        "destination": "/index.html"
    }],
    "ignore": [
        "firebase.json",
        "**/.*",
        "**/node_modules/**"
    ]
}
Lindauson
  • 2,963
  • 1
  • 30
  • 33
  • Did you use '/supplier/accounts' as an example? Because it's not in your routing – Chrillewoodz Jul 10 '15 at 15:29
  • Failing to see how Firebase or AngularFire having anything to do with your routes. Also, as mentioned by @Chrillewoodz, the code above doesn't run. – Kato Jul 10 '15 at 21:30
  • @Chrillewoodz: the `'accounts'` state inherits the base url of the `'/supplier'` abstract state. This works as intended (and per the docs [here](https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views),) but only when `$locationProvider.html5Mode` is false. – Lindauson Jul 11 '15 at 17:23
  • @Kato: My app is being hosted on Firebase. I read in the docs [here](https://www.firebase.com/docs/hosting/guide/full-config.html), that Firebase now supports HTML5 pushState. Is there something wrong with how I am implementing this? – Lindauson Jul 11 '15 at 17:28
  • Dupcilate of http://stackoverflow.com/questions/24206362/angularjs-html5mode. See https://www.firebase.com/docs/hosting/guide/url-redirects-rewrites.html – Kato Jul 14 '15 at 21:59
  • @Kato: I'm slightly confused; my comment to you (just before your most recent comment) contains the same link your referencing. Moreover, I'm using the suggested rewrite from that page in the original question. – Lindauson Jul 15 '15 at 13:44
  • I think the problem lies in how I am resolving non-root urls in angular-ui. I'll test it out and report back here, as soon as I can. – Lindauson Jul 15 '15 at 13:51

1 Answers1

0

(Took a look at the bug fix I pushed so this question doesn't remain unanswered.)

Turns out it was my Gruntfile. I needed to update my LiveReload config in my Grunt server settings. Your LiveReload changes should look like this:

// Grunt configuration
grunt.initConfig({

    // Project settings
    your_application_name: appConfig,

    // The grunt server settings
    connect: {
        options: {
            port: 8000,
            hostname: 'localhost',
            livereload: 35729
        },
        livereload: {
            options: {
                open: true,
                middleware: function (connect) {
                    return [
                        modRewrite(['^[^\\.]*$ /index.html [L]']),
                        connect.static('.tmp'),
                        connect().use(
                            '/bower_components',
                            connect.static('./bower_components')
                        ),
                        connect.static(appConfig.app)
                    ];
                }
            }
        }
        //...
    }
});
Lindauson
  • 2,963
  • 1
  • 30
  • 33