---
agentTools:
  projectIndex: https://docs.usecreator.com/llms.txt
---

# Making a Simple Chat App

Let's blast off with a Firebase connected group chatting app! 🚀

[block:html]
{
  "html": "<script src=\"//fast.wistia.com/embed/medias/ygbuyr1ztr.jsonp\" async></script><script src=\"//fast.wistia.com/assets/external/E-v1.js\" async></script><div class=\"wistia_responsive_padding\" style=\"padding:56.25% 0 0 0;position:relative;\"><div class=\"wistia_responsive_wrapper\" style=\"height:100%;left:0;position:absolute;top:0;width:100%;\"><div class=\"wistia_embed wistia_async_ygbuyr1ztr videoFoam=true\" style=\"height:100%;width:100%\">&nbsp;</div></div></div>"
}
[/block]

Here's the final code from the end of the video:

[block:code]
{
  "codes": [
    {
      "code": ".top-container{\n    height: calc(100% - 96px);\n    overflow:scroll;\n}\n\n.bottom-form{\n    position:absolute;\n    bottom:0px;\n    display:block;\n    width:100%;\n    background-color:white;\n    button{\n        margin:0px !important;\n    }\n}",
      "language": "scss",
      "name": "theme.scss"
    },
    {
      "code": "// The following is the constructor function for this page's controller. See https://docs.angularjs.org/guide/controller\n// You can include any angular dependencies as parameters for this function\n// TIP: Access Route Parameters for your page via $stateParams.parameterName\nfunction ($scope, $stateParams, $firebaseArray, $ionicUser) {\n    \n    $scope.data = {\n        'message': ''\n    }\n    \n      var ref = firebase.database().ref().child(\"messages\");\n      // create a synchronized array\n      $scope.messages = $firebaseArray(ref);\n      \n      // add new items to the array\n      // the message is automatically added to our Firebase database!\n      $scope.addMessage = function() {\n        $scope.messages.$add({\n          text: $scope.data.message,\n          email: $ionicUser.details.email,\n          name: $ionicUser.details.name\n        });\n        $scope.data.message = '';\n      };\n\n}",
      "language": "javascript",
      "name": "Chat.page-controller.js"
    },
    {
      "code": "/* angularjs Scroll Glue\n * version 2.0.7\n * https://github.com/Luegg/angularjs-scroll-glue\n * An AngularJs directive that automatically scrolls to the bottom of an element on changes in it's scope.\n*/\n\n// Allow module to be loaded via require when using common js. e.g. npm\nif(typeof module === \"object\" && module.exports){\n    module.exports = 'luegg.directives';\n}\n\n(function(angular, undefined){\n    'use strict';\n\n    function createActivationState($parse, attr, scope){\n        function unboundState(initValue){\n            var activated = initValue;\n            return {\n                getValue: function(){\n                    return activated;\n                },\n                setValue: function(value){\n                    activated = value;\n                }\n            };\n        }\n\n        function oneWayBindingState(getter, scope){\n            return {\n                getValue: function(){\n                    return getter(scope);\n                },\n                setValue: function(){}\n            };\n        }\n\n        function twoWayBindingState(getter, setter, scope){\n            return {\n                getValue: function(){\n                    return getter(scope);\n                },\n                setValue: function(value){\n                    if(value !== getter(scope)){\n                        scope.$apply(function(){\n                            setter(scope, value);\n                        });\n                    }\n                }\n            };\n        }\n\n        if(attr !== \"\"){\n            var getter = $parse(attr);\n            if(getter.assign !== undefined){\n                return twoWayBindingState(getter, getter.assign, scope);\n            } else {\n                return oneWayBindingState(getter, scope);\n            }\n        } else {\n            return unboundState(true);\n        }\n    }\n\n    function createDirective(module, attrName, direction){\n        module.directive(attrName, ['$parse', '$window', '$timeout', function($parse, $window, $timeout){\n            return {\n                priority: 1,\n                restrict: 'A',\n                link: function(scope, $el, attrs){\n                    var el = $el[0],\n                        activationState = createActivationState($parse, attrs[attrName], scope);\n\n                    function scrollIfGlued() {\n                        if(activationState.getValue() && !direction.isAttached(el)){\n                            direction.scroll(el);\n                        }\n                    }\n\n                    function onScroll() {\n                        activationState.setValue(direction.isAttached(el));\n                    }\n\n                    scope.$watch(scrollIfGlued);\n\n                    $timeout(scrollIfGlued, 0, false);\n\n                    $window.addEventListener('resize', scrollIfGlued, false);\n\n                    $el.on('scroll', onScroll);\n\n\n                    // Remove listeners on directive destroy\n                    $el.on('$destroy', function() {\n                        $el.unbind('scroll', onScroll);\n                    });\n\n                    scope.$on('$destroy', function() {\n                        $window.removeEventListener('resize', scrollIfGlued, false);\n                    });\n                }\n            };\n        }]);\n    }\n\n    var bottom = {\n        isAttached: function(el){\n            // + 1 catches off by one errors in chrome\n            return el.scrollTop + el.clientHeight + 1 >= el.scrollHeight;\n        },\n        scroll: function(el){\n            el.scrollTop = el.scrollHeight;\n        }\n    };\n\n    var top = {\n        isAttached: function(el){\n            return el.scrollTop <= 1;\n        },\n        scroll: function(el){\n            el.scrollTop = 0;\n        }\n    };\n\n    var right = {\n        isAttached: function(el){\n            return el.scrollLeft + el.clientWidth + 1 >= el.scrollWidth;\n        },\n        scroll: function(el){\n            el.scrollLeft = el.scrollWidth;\n        }\n    };\n\n    var left = {\n        isAttached: function(el){\n            return el.scrollLeft <= 1;\n        },\n        scroll: function(el){\n            el.scrollLeft = 0;\n        }\n    };\n\n    var module = angular.module('luegg.directives', []);\n\n    createDirective(module, 'scrollGlue', bottom);\n    createDirective(module, 'scrollGlueTop', top);\n    createDirective(module, 'scrollGlueBottom', bottom);\n    createDirective(module, 'scrollGlueLeft', left);\n    createDirective(module, 'scrollGlueRight', right);\n}(angular));",
      "language": "javascript",
      "name": "scrollglue.js"
    }
  ]
}
[/block]