bootstrap + web firebase realtime + firebase storage

Auth:Use Email&password then input one user with email & password. Login use be added user.

index.html

  
<!doctype html>  
<html lang="zh-Hant-TW">  
  <head>  
    <!-- Required meta tags -->  
    <meta charset="utf-8">  
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">  
  
    <!-- Bootstrap CSS -->  
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">  
    <link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/4.0.0/firebaseui.css" />  
  
    <title>Hello, world!</title>  
  </head>  
  <body>  
    <div class="container">  
        <div id="firebaseui-auth-container" class="alert alert-light" role="alert"></div>  
    </div>  
      
    <div class="container my-1">  
        <div class="row">  
            <div class="col-sm">Login Status  
                <div class="user-signed-in" style="display: none;"><span class="badge badge-pill badge-success">user-signed-in</span></div>  
                <div class="user-signed-out" style="display: none;"><span class="badge badge-pill badge-secondary">user-signed-out</span></div>  
            </div>  
            <div class="col-sm"><a class="btn btn-outline-primary" data-toggle="collapse" href="#multiCollapseExample1" role="button" aria-expanded="false" aria-controls="multiCollapseExample1">Account Details</a>  
                <div class="collapse multi-collapse" id="multiCollapseExample1">  
                    <div class="card card-body">  
                        <pre id="account-details">...</pre>  
                    </div>  
                </div>  
            </div>  
        </div>  
    </div>  
  
    <div class="container my-1">  
        <div class="row justify-content-end">  
            <div class="col-2">  
                <div id="sign-in" class="btn btn-outline-primary" style="display: none;">sign-in</div>  
                <div id="sign-out" class="btn btn-outline-danger" style="display: none;">sign-out</div>  
            </div>  
        </div>  
    </div>  
  
    <div class="container my-1">  
        <div class="row justify-content-center">  
            <div id="loading" class="spinner-border" role="status">  
                <span class="sr-only">Loading...</span>  
            </div>  
        </div>  
    </div>  
      
    <div class="container my-1">  
        <div id="loaded" class="user-signed-in" style="display: none;">檔案上傳  
            <div id="filesubmit">  
                <input type="file" class="file-select" accept="image/*"/>  
                <button class="file-submit">SUBMIT</button>  
            </div>  
        </div>  
    </div>  
  
    <div class="container my-1">  
        <div class="row">  
            <div class="col-2">  
                <div id="test" class="btn btn-outline-primary">test</div>  
            </div>  
        </div>  
    </div>  
      
        <!-- Optional JavaScript -->  
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->  
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>  
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>  
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>  
    <script src="https://cdn.firebase.com/libs/firebaseui/4.0.0/firebaseui.js"></script>  
    <script src="https://www.gstatic.com/firebasejs/ui/4.0.0/firebase-ui-auth__zh_tw.js"></script>  
  
    <script defer src="https://www.gstatic.com/firebasejs/6.3.0/firebase-app.js"></script>  
    <script defer src="https://www.gstatic.com/firebasejs/6.3.0/firebase-auth.js"></script>  
    <script defer src="https://www.gstatic.com/firebasejs/6.3.0/firebase-database.js"></script>  
    <!--<script defer src="https://www.gstatic.com/firebasejs/6.3.0/firebase-firestore.js"></script>-->  
    <script defer src="https://www.gstatic.com/firebasejs/6.3.0/firebase-storage.js"></script>  
      
    <script defer src="./init-firebase.js"></script>  
    <script>  
          
    </script>  
    <script>  
        document.getElementById('test').addEventListener('click', function() {  
            var fbdbpath = getfbdbPath('images/@/default/');  
            putimageurl(fbdbpath, 'url');  
        });  
          
        function fileupload(){ //== File upload ========================  
            document.querySelector('.file-select').addEventListener('change', handleFileUploadChange);  
            document.querySelector('.file-submit').addEventListener('click', handleFileUploadSubmit);  
              
            let selectedFile;  
  
            function handleFileUploadChange(e) {  
                selectedFile = e.target.files[0];  
            }  
  
            function handleFileUploadSubmit(e) {  
                var metadata = {  
                    contentType: 'image/jpeg'  
                };  
  
                var fbdbpath = getfbdbPath('images/@/default/');  
                var newfbdbPostKey= getfbdbPostKey(fbdbpath);  
                var uploadTask = imagesRef.child(`${newfbdbPostKey}`).put(selectedFile, metadata);  
  
                uploadTask.on('state_changed', function(snapshot){  
                    var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;  
                    console.log('Upload is ' + progress + '% done');  
                    switch (snapshot.state) {  
                        case firebase.storage.TaskState.PAUSED: // or 'paused'  
                        console.log('Upload is paused');  
                        break;  
                        case firebase.storage.TaskState.RUNNING: // or 'running'  
                        console.log('Upload is running');  
                        break;  
                    }  
                    }, function(error) {  
                        // Handle unsuccessful uploads  
                        alert('Upload is Failed;');  
                        console.log(error);  
                    }, function() {  
                        uploadTask.snapshot.ref.getDownloadURL().then(function(downloadURL) {  
                            console.log('File available at', downloadURL);  
                            putimageurl(fbdbpath, downloadURL);  
                        });  
                    }  
                );  
            }  
        }  
  
  
        function initsign(){ //== Auth ===============================  
            document.getElementById('sign-in').addEventListener('click', function() {  
                if($('.user-signed-out').css('display') === 'block') ui.start('#firebaseui-auth-container', getUiConfig());  
            });  
  
            document.getElementById('sign-out').addEventListener('click', function() {  
                var user = firebase.auth().currentUser;  
  
                if (user) {  
                    firebase.auth().signOut().then((res)=>{  
                        console.log('signOut ok', res);  
                    }).catch((err)=>{  
                        alert('Logout Failed!');  
                        console.warn('signOut error',res);  
                    }).finally((res)=>{  
                        console.log('signOut resolved', res);  
                        location.reload();  
                    });  
                }  
            });  
        }  
  
    </script>  
  
  </body>  
</html>  

init-firebase.js

  
var firebaseConfig  = {  
  apiKey: 'AIzaSyBxxxxxxooooo',  
  authDomain: 'product-xxxxxxooooo.firebaseapp.com',  
  databaseURL: 'https://product-xxxxxxooooo.firebaseio.com',  
  storageBucket: 'gs://product-xxxxxxooooo.appspot.com'  
};  
firebase.initializeApp(firebaseConfig);  
  
//== database ===========================  
var database = firebase.database();  
  
function getfbdbPath(type){  
  var userId = firebase.auth().currentUser.uid;  
  return type.replace("@", userId);  
}  
  
function getfbdbPostKey(path){  
  return firebase.database().ref().child(path).push().key;  
}  
  
function putimageurl(path, url){  
  //var userId = firebase.auth().currentUser.uid;  
  var path = getfbdbPath('images/@/default/');  
  var postImg = {  
    active: true,  
    url: url,  
  };  
  
  var newPostKey = getfbdbPostKey(path);  
  var images = {};  
  images[path + newPostKey] = postImg;  
  //updates['/user-posts/' + userId + '/' + newPostKey] = postData;  
  
  var uploadImagesResult = firebase.database().ref().update(images);  
  console.log('uploadImagesResult');  
  console.log(uploadImagesResult);  
}  
  
function test(){  
  var userId = firebase.auth().currentUser.uid;  
  
  firebase.database().ref('users/' + userId).set({  
    username: 'name',  
    email: 'email',  
    profile_picture : 'imageUrl'  
  }, function(error) {  
    if (error) {  
      console.log(error)  
      // The write failed...  
    } else {  
      // Data saved successfully!  
      console.log("successfullly!")  
    }  
  });  
  
  var c = firebase.database().ref('/users/' + userId).once('value').then(function(snapshot) {  
    var username = (snapshot.val() && snapshot.val().username) || 'Anonymous';  
    // ...  
    console.log("username:", username);  
  });  
  console.log('c');  
  console.log(c);  
  
  var postData = {  
    author: 'username',  
    uid: userId,  
  };  
  var newPostKey = firebase.database().ref().child('posts').push().key;  
  var updates = {};  
  updates['/posts/' + newPostKey] = postData;  
  //updates['/user-posts/' + userId + '/' + newPostKey] = postData;  
  //firebase.database().ref('posts/' + userId).set(postData);  
  
  var t = firebase.database().ref().update(updates);  
  console.log('t');  
  console.log(t);  
}  
  
  
//== File upload ========================  
var storageRef = firebase.storage().ref();  
var imagesRef = storageRef.child('images');  
  
// var otherProject = firebase.initializeApp(firebaseConfig, 'other');  
// console.log(otherProject.name);    // "otherProject"  
// var otherStorage = otherProject.storage();  
  
//== Auth ===============================  
function getUiConfig() {  
  return {  
    signInSuccessUrl: this.location.href,  
    signInOptions: [  
      firebase.auth.EmailAuthProvider.PROVIDER_ID,  
    ],  
    //immediateFederatedRedirect: false,  
  };  
}  
  
// Initialize the FirebaseUI Widget using Firebase.  
var ui = new firebaseui.auth.AuthUI(firebase.auth());  
// The start method will wait until the DOM is loaded.  
if (ui.isPendingRedirect()) {  
  ui.start('#firebaseui-auth-container', getUiConfig());  
}  
// Disable auto-sign in.  
// ui.disableAutoSignIn();  
  
var handleSignedInUser = function(user) {  
  $('.user-signed-in').show();  
  $('.user-signed-out').hide();  
  $('#sign-in').hide();  
  $('#sign-out').show();  
  document.getElementById('account-details').textContent = user.displayName;  
  user.getIdToken().then(function(accessToken) {  
    document.getElementById('account-details').textContent =   
      JSON.stringify({  
        displayName: user.displayName,  
        email: user.email,  
        emailVerified: user.emailVerified,  
        phoneNumber: user.phoneNumber,  
        photoURL: user.photoURL,  
        uid: user.uid,  
        accessToken: user.accessToken,  
        providerData: user.providerData  
      }, null, '  ');  
  });  
};  
  
var handleSignedOutUser = function() {  
  $('.user-signed-in').hide();  
  $('.user-signed-out').show();  
  $('#sign-in').show();  
  $('#sign-out').hide();  
  //ui.start('#firebaseui-container', getUiConfig());  
};  
  
function handleConfigChange() {  
  // Reset the inline widget so the config changes are reflected.  
  ui.reset();  
  ui.start('#firebaseui-container', getUiConfig());  
}  
  
firebase.auth().onAuthStateChanged(function(user) {  
  document.getElementById('loading').style.display = 'none';  
  document.getElementById('loaded').style.display = 'block';  
  user ? handleSignedInUser(user) : handleSignedOutUser();  
}, function(error) {  
  console.log(error);  
});  
  
initsign();  
fileupload();  

firebase realtime database rule

95dWpHhg5wOk1loIj0iTneWdfwG2 is admin user <= userId = firebase.auth().currentUser.uid;```

{

“rules”: {

“.read”: “‘95dWpHhg5wOk1loIj0iTneWdfwG2’ === auth.uid”,

“users”: {

“$uid”: {

“.write”: “$uid === auth.uid”

}

},

“images”: {

“.write”: “‘95dWpHhg5wOk1loIj0iTneWdfwG2’ === auth.uid”,

}

}

}

  

firebase storage rule
---------------------

95dWpHhg5wOk1loIj0iTneWdfwG2 is admin user <= userId = firebase.auth().currentUser.uid;```
  
  
rules_version = '2';  
  
service firebase.storage {  
  
match /b/{bucket}/o {  
  
match /{allPaths=**} {  
  
allow read;  
  
allow write: if '95dWpHhg5wOk1loIj0iTneWdfwG2' == request.auth.uid;  
  
}  
  
}  
  
}