# (Optional) Assignment 5: Tok: Firebase and Playing Video

## Goals
- learn to use external database, storage
- AVKit

**Note:** If you do this assignment, ((the grade will be averaged in with your
other projects**. It is *not* a bonus, or extra credit. However, we will
only count the assignment if it is better than your current average
assignment store, so it can not hurt your grade.  

## Approach

In this project we are going to build a pared-down version of
TikTok. You are going to build an app that allows you to upload
URLs of online videos to a database, play those videos, and "like"
your favorites. 

We will be using the Firebase Realtime Database to store the URLs,
"likes", and viewing information.



## Steps
There are many steps to this project; I encourage you to start early.

### Step 1: Set Up Your Database and Create Your App
In this step we are going to set up an iOS app and tie it into the
database. 

- Create a brand new app called `assign5` in your repository. 
  - no tests
- Go to [http://firebase.google.com/](http://firebase.google.com/) and
register for the free Spark Plan.
  - Work through the [this
  guide](https://firebase.google.com/docs/ios/setup?authuser=0) to
  setting up a project. 
  - Name your Firebase project `assign5` as well, create a realtime database, and do not forget to download `GoogleService-Info.plist`
  - Your `Podfile` should consist of the following:

```
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'openTok' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for openTok
  pod 'Firebase/Database'
end
```

***Important***, to add the firebase configure code to your app, follow the notes/vid from class.

  - You do not need to know much about
    [Cocoapods](https://cocoapods.org/). Create the above
    Podfile in your top `assign5` directory. Install Cocoapods on your machine if you don't already
    have it. Easiest is to use `sudo gem install cocoapods`, but if
    you don't have root access look [here](https://guides.cocoapods.org/using/getting-started.html)
		under "Sudo-less Installation". Then type `pod install` on the command line inside your top `assign5` directory.
		From then on, **always open assign5.xcworkspace** instead of "assign5.xcodeproj".


Try out your database!  Go to [https://console.firebase.google.com](https://console.firebase.google.com/u/0/), create the realtime database if you haven't already, and then click on 'Realtime Database'. Click on rules:

![rules](rules.png) 

Set up both read and write rules as true.

Now go to the data tab. Real-time means that as you insert data from your app, it will magically appear in the browser window (see the demo for an example). Assuming you have correctly set up cocoapods, and the `GoogleService-Info.plist`. In your ContentView.swift, you should be able to try the following code: 
```
struct ContentView: View {
    
    func upload() {
        FirebaseApp.configure()
        let root = Database.database().reference()
        root.child("urls").childByAutoId().setValue(["name": "Neo romps happily in the snow", "url": "https://sedna.cs.umd.edu/436clips/vids/neo.mp4"])
    }
    
    var body: some View {
        Button(action: upload) {"Upload"}
    }
}
 ```
You should see the following on  your firebase console. Remember to import `Firebase` and `FirebaseDatabase` on top of your file:

![rules](data.png)



## Step 2: Lay Out Your View

You should end up with at least two additional View files, named as
`UploadView.swift` and `PlayerView.swift` (You may name them as you
want and create more files if needed). You should be using
*NavigationViews* throughout.

## Step 3: Build the URL Uploader View 
This view will just allow the user to input a URL and description (through `TextField`s) and insert into
the database. A url, name, and date can be inserted to firebase as follows:
```
root.child("urls").childByAutoId().setValue(["name": "Meditation Sheep", 
                                             "url": "https://sedna.cs.umd.edu/436clips/vids/sheep.mp4"])
                                             "date": Date().mysql()])
```
Use of the `childByAutoID()` guarantees a unique key, even with simultaneous insertions
into the database.

Use an "Upload" button or to affirmatively trigger the database insertion.

Note that you can edit and delete data in the database from the console browser
window. Hover the mouse to the right of data and you will see options.


## Step 4: Create a Video Player
In line with **All-SwiftUI, All-the-Time** (ASAT), use only the SwiftUI approach, i.e.:
```
VideoPlayer(player: AVPlayer(url: "..."))
```
Do not use UIKit-based  methods to display videos.  Do not use layers,
etc.  This results in slightly reduced functionality, but we're about
learning the latest approaches here, and by next year all the old
cruft will probably have been replaced.

What else do we need to do?
- Show the Name, show the number of likes
- Add controls for going to the next and previous videos.
- Add a "like" control.
- Allow swipes up and down to go to the next and previous videos.
- Allow a swipe right to add a "like".


## Step 5: Going Live on a Shared Database
After getting your code running on your own database, you can try running it against our
shared database.
Download the Firebase property list [here](GoogleService-Info.plist).

**Please note:** There are no permissions, and any one of you can blow away or mess up the
entire database. Please be very careful when you start using this live database so as not
to annoy all the other users. 

**Please also note:** Uploading any inappropriate URLs will be reported to the proper
university officials. There are 150 students in the class, from every conceivable
background. This is not the place have fun with NSFW videos, or to argue your political
stance. Please report any violations to me; I can track who inserted what into the DB.

## Running on your phone (we will not test)
Need to make sure your phone trusts the developer. When attempting to run on your phone, you may receive
a "signature not trusted by phone" or some such (this is not the exact wording). When this
happens you can go into Settings / General / Devide Management and explicitly trust your
developer signature.

Secondly, you may want to explicitly enable the app to use wireless data (though
this might burn through your data plan quickly).


  
## Grading
You should have uploaded at least 4 videos to your database before we test your app, with arbitrary value of likes and seen
- 20 pts: general NavigationView structure, containing links to the player
list of view
  and the URL uploader. 
- 20 pts: URL uploading, downloadable and playable for player 
- 10 pts: showing name/description and number of "likes" over the top of the video
- 10 pts: ordering the URLs as above (unseen first, descending order of links otherwise)
- 10 pts: gesture recognizers
- 10 pts: implementing the "likes" button and functionality
- 10 pts: general look and feel
- 10 pts: one of the following tasks:
  - Record and upload video from inside the app. You can upload anywhere you have access,
    though I suggest using Firebase Storage. 
  - Resize or otherwise modify existing video in your app.

## Video of example app
[video](assign5.mp4)
