├── src ├── components │ ├── constants │ │ ├── roles.js │ │ └── routes.js │ ├── Session │ │ ├── context.js │ │ ├── index.js │ │ ├── withAuthentication.js │ │ └── withAuthorization.js │ ├── Landing │ │ └── index.js │ ├── SignOut │ │ └── index.js │ ├── Home │ │ └── index.js │ ├── SomeComponents │ │ └── index.js │ ├── Firebase │ │ ├── context.js │ │ ├── index.js │ │ └── firebase.js │ ├── Account │ │ └── index.js │ ├── Navigation │ │ └── index.js │ ├── App │ │ └── index.js │ ├── PasswordChange │ │ └── index.js │ ├── Admin │ │ └── index.js │ ├── PasswordForget │ │ └── index.js │ ├── SignIn │ │ └── index.js │ └── SignUp │ │ └── index.js ├── index.css ├── index.js └── serviceWorker.js ├── .firebaserc ├── .gitattributes ├── res └── todo_tree.png ├── public ├── favicon.ico ├── manifest.json └── index.html ├── Kitaplar ├── PDF │ ├── The Road to Graphql.pdf │ ├── The Road to Learn React.pdf │ └── The Road to React with Firebase.pdf └── EPUB │ ├── The Road to Graphql.epub │ ├── The Road to Learn React.epub │ └── The Road to React with Firebase.epub ├── firebase.json ├── .github ├── ISSUE_TEMPLATE │ ├── question.md │ ├── feature_request.md │ └── bug_report.md ├── FUNDING.yml └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── Kişisel Notlar ├── 3 - Kod Notları.md ├── Y - Projenin Temel İlerleyişi.md ├── X - Faydalı Kaynaklar.md ├── 2 - Hızlı Notlar.md ├── 0 - Kurulum ve Kullanım.md └── 1 - Firebase İşlemleri.md ├── package.json ├── LICENSE ├── .firebase └── hosting.YnVpbGQ.cache ├── README-React.md └── README.md /src/components/constants/roles.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "yreact-firebase" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /res/todo_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yemreak/YReact-Firebase/HEAD/res/todo_tree.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yemreak/YReact-Firebase/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /Kitaplar/PDF/The Road to Graphql.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yemreak/YReact-Firebase/HEAD/Kitaplar/PDF/The Road to Graphql.pdf -------------------------------------------------------------------------------- /Kitaplar/EPUB/The Road to Graphql.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yemreak/YReact-Firebase/HEAD/Kitaplar/EPUB/The Road to Graphql.epub -------------------------------------------------------------------------------- /Kitaplar/EPUB/The Road to Learn React.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yemreak/YReact-Firebase/HEAD/Kitaplar/EPUB/The Road to Learn React.epub -------------------------------------------------------------------------------- /Kitaplar/PDF/The Road to Learn React.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yemreak/YReact-Firebase/HEAD/Kitaplar/PDF/The Road to Learn React.pdf -------------------------------------------------------------------------------- /Kitaplar/PDF/The Road to React with Firebase.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yemreak/YReact-Firebase/HEAD/Kitaplar/PDF/The Road to React with Firebase.pdf -------------------------------------------------------------------------------- /Kitaplar/EPUB/The Road to React with Firebase.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yemreak/YReact-Firebase/HEAD/Kitaplar/EPUB/The Road to React with Firebase.epub -------------------------------------------------------------------------------- /src/components/Session/context.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const AuthUserContext = React.createContext(null); 4 | 5 | export default AuthUserContext; 6 | -------------------------------------------------------------------------------- /src/components/Landing/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Landing = () => ( 4 |
5 |

Landing

6 |
7 | ); 8 | 9 | export default Landing; 10 | -------------------------------------------------------------------------------- /src/components/Session/index.js: -------------------------------------------------------------------------------- 1 | import AuthUserContext from "./context"; 2 | import withAuthentication from "./withAuthentication"; 3 | import withAuthorization from "./withAuthorization"; 4 | 5 | export { AuthUserContext, withAuthentication, withAuthorization }; 6 | -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "public": "build", 4 | "ignore": [ 5 | "firebase.json", 6 | "**/.*", 7 | "**/node_modules/**" 8 | ], 9 | "rewrites": [ 10 | { 11 | "source": "**", 12 | "destination": "/index.html" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Sorular 🤔 3 | about: Nasıl kullanacağına dair sorular 4 | --- 5 | 6 | 7 | 8 | ## Question 🤔 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/components/SignOut/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { withFirebase } from "../Firebase"; 3 | 4 | // TODO: Oturum kapatıldığında da yönlendirme olacak 5 | const SignOutButton = ({ firebase }) => ( 6 | 9 | ); 10 | 11 | export default withFirebase(SignOutButton); 12 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/components/Home/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { withAuthorization } from "../Session"; 4 | 5 | const HomePage = () => ( 6 |
7 |

Home

8 |

The Home Page is accessible by every signed in user.

9 |
10 | ); 11 | 12 | const condition = authUser => !!authUser; 13 | 14 | export default withAuthorization(condition)(HomePage); 15 | -------------------------------------------------------------------------------- /src/components/SomeComponents/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { FirebaseContext } from "../Firebase"; 4 | 5 | const SomeComponent = () => ( 6 | 7 | {firebase => { 8 | return
I've access to Firebase and render something.
; 9 | }} 10 |
11 | ); 12 | 13 | export default SomeComponent; 14 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/components/constants/routes.js: -------------------------------------------------------------------------------- 1 | // TIP: Websitesi sayfaları 2 | // src\components\Navigation\index.js ile alakalıdır. 3 | export const LANDING = "/"; 4 | export const SIGN_UP = "/signup"; 5 | export const SIGN_IN = "/signin"; 6 | export const HOME = "/home"; 7 | export const ACCOUNT = "/account"; 8 | export const ADMIN = "/admin"; 9 | export const PASSWORD_FORGET = "/pw-forget"; 10 | export const SOME_COMPONENT = "/some-component"; 11 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: yemreak # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | custom: # Replace with a single custom sponsorship URL 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | # Kişisel dosyalar 26 | desktop.ini 27 | .env* 28 | -------------------------------------------------------------------------------- /src/components/Firebase/context.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const FirebaseContext = React.createContext(null); 4 | 5 | // TIP: Firebase ile component kullanımı 6 | 7 | /** 8 | * Firebase props'una erişim hakkı ile componenti çağırma 9 | * @param {React.Component} Component Firebase erişimi verilecek React Componenti 10 | */ 11 | export const withFirebase = Component => props => ( 12 | 13 | {firebase => } 14 | 15 | ); 16 | 17 | export default FirebaseContext; 18 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Özet 4 | 5 | 6 | 7 | 8 | ## Değişikler 9 | 10 | 11 | - 12 | - 13 | 14 | ## Gözden Geçireceklere Tavsiyeler 15 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Özellik Önerisi 💡 3 | about: Parlak fikirlerin varsa, lütfen saklama 4 | 5 | --- 6 | 7 | 8 | 9 | ## Özellik Özeti 💡 10 | 11 | 12 | 13 | 14 | ## Neden bu özelliğe ihtiyacımız olsun? 15 | 16 | 17 | 18 | 19 | ## Bunu nasıl uygulamayı tavsiye edersin? 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/components/Account/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { PasswordForgetForm } from "../PasswordForget"; 4 | import PasswordChangeForm from "../PasswordChange"; 5 | 6 | import { AuthUserContext, withAuthorization } from "../Session"; 7 | 8 | const AccountPage = () => ( 9 | 10 | {authUser => ( 11 |
12 |

Account: {authUser.email}

13 | 14 | 15 |
16 | )} 17 |
18 | ); 19 | 20 | const condition = authUser => !!authUser; 21 | 22 | export default withAuthorization(condition)(AccountPage); 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Hata bildirme 🐞 3 | about: Herhangi bir şey istendiği gibi çalışmıyor mu? 4 | --- 5 | 6 | 7 | 8 | ## Hata Özeti 🐞 9 | 10 | 11 | 12 | 13 | ## Hatayı Engelleme Adımları: 14 | 15 | 16 | 1. 17 | 2. 18 | 19 | 20 | 21 | 22 | ## Önerin Nedir? 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Kişisel Notlar/3 - Kod Notları.md: -------------------------------------------------------------------------------- 1 | # Kod Notları 2 | 3 | ## With Metodlarının Kullanımları 4 | 5 | | Metod | `this.props.` objesi | Sağladığı işlemler | 6 | | -------------------- | -------------------- | ------------------------- | 7 | | `withFirebase` | `firebase` | Firabase | 8 | | `withRouter` | `history` | Sayfa yönlendirme | 9 | | `withAuthorization` | | Koşullu sayfa yönlendirme | 10 | | `withAuthentication` | `authUser` | Kullanıcı kimlik erişimi | 11 | 12 | ### Authorization Metodu 13 | 14 | ```jsx 15 | // Yönlendirme koşulu 16 | const condition = authUser => !!authUser; 17 | export default withAuthorization(condition)(AdminPage); 18 | ``` 19 | -------------------------------------------------------------------------------- /src/components/Firebase/index.js: -------------------------------------------------------------------------------- 1 | // TIP: Firebase'e erişims 2 | /* The createContext() function essentially creates two components. The FirebaseContext.Provider component is used to provide a Firebase instance once at the top-level of your React component tree, which we will do in this section; and the FirebaseContext.Consumer component is used to retrieve the Firebase instance if it is needed in the React component. For a well-encapsulated Firebase module, we’ll define a index.js file in our Firebase folder that exports all necessary functionalities (Firebase class, Firebase context for Consumer and Provider components): */ 3 | 4 | import FirebaseContext, { withFirebase } from "./context"; 5 | import Firebase from "./firebase"; 6 | 7 | export default Firebase; 8 | 9 | export { FirebaseContext, withFirebase }; 10 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import "./index.css"; 4 | import * as serviceWorker from "./serviceWorker"; 5 | 6 | import App from "./components/App"; 7 | import Firebase, { FirebaseContext } from "./components/Firebase"; 8 | 9 | // TIP: Firebase'in tüm componentler için tanımlanması (React Context API) 10 | // React Context API ile firebase tüm componentlerin üstünde tanımlanmıştır 11 | ReactDOM.render( 12 | 13 | 14 | , 15 | document.getElementById("root") 16 | ); 17 | 18 | // If you want your app to work offline and load faster, you can change 19 | // unregister() to register() below. Note this comes with some pitfalls. 20 | // Learn more about service workers: https://bit.ly/CRA-PWA 21 | serviceWorker.unregister(); 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-firebase-authentication", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "firebase": "^6.3.4", 7 | "react": "^16.8.6", 8 | "react-dom": "^16.8.6", 9 | "react-router-dom": "^5.0.1", 10 | "react-scripts": "3.0.1", 11 | "recompose": "^0.30.0" 12 | }, 13 | "scripts": { 14 | "start": "react-scripts start", 15 | "build": "react-scripts build", 16 | "test": "react-scripts test", 17 | "eject": "react-scripts eject" 18 | }, 19 | "eslintConfig": { 20 | "extends": "react-app" 21 | }, 22 | "browserslist": { 23 | "production": [ 24 | ">0.2%", 25 | "not dead", 26 | "not op_mini all" 27 | ], 28 | "development": [ 29 | "last 1 chrome version", 30 | "last 1 firefox version", 31 | "last 1 safari version" 32 | ] 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Yunus Emre 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/components/Navigation/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | import { AuthUserContext } from "../Session"; 4 | 5 | import * as ROUTES from "../constants/routes"; 6 | import SignOutButton from "../SignOut"; 7 | 8 | // TIP: Sayfa yönlendirme işlemleri 9 | 10 | const Navigation = () => ( 11 | 12 | {authUser => (authUser ? : )} 13 | 14 | ); 15 | 16 | const NavigationAuth = () => ( 17 | 34 | ); 35 | 36 | const NavigationNonAuth = () => ( 37 | 48 | ); 49 | 50 | export default Navigation; 51 | -------------------------------------------------------------------------------- /src/components/Session/withAuthentication.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import AuthUserContext from "./context"; 4 | import { withFirebase } from "../Firebase"; 5 | 6 | /** 7 | * Verilen component'e `authUser` state'ine erişim hakkı verir 8 | * @param {React.Component} Component React componenti 9 | */ 10 | const withAuthentication = Component => { 11 | class WithAuthentication extends React.Component { 12 | constructor(props) { 13 | super(props); 14 | 15 | this.state = { 16 | authUser: null 17 | }; 18 | } 19 | 20 | componentDidMount() { 21 | // TIP: Giriş yapıldı mı kontorlü 22 | // WARN: Listener component unmount olduğunda kaldırlmazsa performans kaybına neden olur. 23 | this.listener = this.props.firebase.auth.onAuthStateChanged(authUser => { 24 | authUser 25 | ? this.setState({ authUser }) 26 | : this.setState({ authUser: null }); 27 | }); 28 | } 29 | 30 | componentWillUnmount() { 31 | // Performans kaybını engellemek için listenerı kapatıyoruz 32 | this.listener(); 33 | } 34 | 35 | render() { 36 | return ( 37 | 38 | 39 | 40 | ); 41 | } 42 | } 43 | 44 | return withFirebase(WithAuthentication); 45 | }; 46 | 47 | export default withAuthentication; 48 | -------------------------------------------------------------------------------- /.firebase/hosting.YnVpbGQ.cache: -------------------------------------------------------------------------------- 1 | asset-manifest.json,1566392164538,103b810b7591417fda0ab05d8383f00c9096a8f1120c9b4bb4818fdab8eff0d2 2 | manifest.json,1565771244404,6b50377417dc0a8a86bd922f13eaf38a3670b6a23cc5ce3da3efd594cc3a2741 3 | index.html,1566392164538,f61532551712bf4e9a0ce3ee124e2ef3d6e6a1e9a98fa3b718301dbcbec4ecf4 4 | precache-manifest.6d034fa55db2b36300e5d0fb4164990d.js,1566392164538,d81e6db5ed526ad210e2457bab739eb302d28c95e17988351f70fbf713292700 5 | service-worker.js,1566392164538,a87afb61fcf0ed6330be13ea1298f16238b641849fe6fb559ecc07e745957ac9 6 | static/css/main.498d002a.chunk.css,1566392164541,d163c946ef4ab705820ed6b5e371942a4665488974c4d5f254b01b4c4afe3a8c 7 | static/js/main.9f2bd0ea.chunk.js,1566392164540,d8b04dcdb809d965fa8baae85a02c82bfece7e5b22289f562a27b7b9385ef188 8 | static/js/runtime~main.a8a9905a.js,1566392164550,27518aed75eb917ee7575e8c911b596e850b5265b9e5694a7681cba901419f4d 9 | static/js/runtime~main.a8a9905a.js.map,1566392164550,d13b46ae2acf0d2863e1c6449a51f64702fa5b464c475c0ec20d6e8de9970ef9 10 | favicon.ico,1565771244403,eae62e993eb980ec8a25058c39d5a51feab118bd2100c4deebb2a9c158ec11f9 11 | static/css/main.498d002a.chunk.css.map,1566392164549,7125bb737a0128f1d42f5c9403198477f7e4badcf6ad6c129f502f354bd4c318 12 | static/js/main.9f2bd0ea.chunk.js.map,1566392164550,93fa9883e1eecf0e6b9eb6254b84964d98143494fe32c876978ddb9cf9d0ebe4 13 | static/js/2.ce3904c9.chunk.js,1566392164550,cd010659f3b3f2a96595276ab3333097841b153c26799f3aa1b2c95e5f19e183 14 | static/js/2.ce3904c9.chunk.js.map,1566392164550,d49c9f43e908b54873d63db8ca897c235335454af20570af5ffdb25a539cda5b 15 | -------------------------------------------------------------------------------- /src/components/App/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { BrowserRouter as Router, Route } from "react-router-dom"; 3 | 4 | import { withAuthentication } from "../Session"; 5 | 6 | import Navigation from "../Navigation"; 7 | import LandingPage from "../Landing"; 8 | import SignUpPage from "../SignUp"; 9 | import SignInPage from "../SignIn"; 10 | import PasswordForgetPage from "../PasswordForget"; 11 | import HomePage from "../Home"; 12 | import AccountPage from "../Account"; 13 | import AdminPage from "../Admin"; 14 | import SomeComponent from "../SomeComponents"; 15 | 16 | import * as ROUTES from "../constants/routes"; 17 | 18 | /* 19 | Bu alanda yapıalcak her değişiklik için alttaki alanlar değişmeli: 20 | - "../constant/routes" 21 | - "../Navigation" 22 | */ 23 | 24 | const App = () => ( 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 | ); 39 | 40 | // Oturum bilgisine erişimli App verisini döndürmemiz lazım, çünkü oturum işlemlerini kullanıyor 41 | export default withAuthentication(App); 42 | -------------------------------------------------------------------------------- /src/components/Session/withAuthorization.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { compose } from "recompose"; 4 | 5 | import { withRouter } from "react-router-dom"; 6 | import { withFirebase } from "../Firebase"; 7 | 8 | import AuthUserContext from "./context"; 9 | 10 | import * as ROUTES from "../constants/routes"; 11 | 12 | // TIP: Koşullu yönlendirme yapısı 13 | 14 | /** 15 | * Koşullu olarak `SIGN_IN` sayfasına yönlendirme 16 | * - Herkese gösterilmeyen sayfaların yönetimi için kullanılır 17 | * - Verilen component'e firebase erişimi verir 18 | * @param {function} condition Koşul fonksiyonu (true ise `Component` aksi halde `null`) 19 | */ 20 | const withAuthorization = condition => Component => { 21 | class WithAuthorization extends React.Component { 22 | componentDidMount() { 23 | this.listener = this.props.firebase.auth.onAuthStateChanged(authUser => { 24 | if (!condition(authUser)) { 25 | this.props.history.push(ROUTES.SIGN_IN); 26 | } 27 | }); 28 | } 29 | 30 | componentWillUnmount() { 31 | this.listener(); 32 | } 33 | 34 | render() { 35 | return ( 36 | // Yönlendirme yapılmadan sayfanın gözükmesini engelleme 37 | 38 | {authUser => 39 | condition(authUser) ? : null 40 | } 41 | 42 | ); 43 | } 44 | } 45 | 46 | return compose( 47 | withRouter, 48 | withFirebase 49 | )(WithAuthorization); 50 | }; 51 | 52 | export default withAuthorization; 53 | -------------------------------------------------------------------------------- /src/components/Firebase/firebase.js: -------------------------------------------------------------------------------- 1 | import app from "firebase/app"; 2 | import "firebase/auth"; 3 | import "firebase/database"; 4 | 5 | // TIP: Firebase yapılandırması 6 | const config = { 7 | apiKey: process.env.REACT_APP_API_KEY, 8 | authDomain: process.env.REACT_APP_AUTH_DOMAIN, 9 | databaseURL: process.env.REACT_APP_DATABASE_URL, 10 | projectId: process.env.REACT_APP_PROJECT_ID, 11 | storageBucket: process.env.REACT_APP_STORAGE_BUCKET, 12 | messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID, 13 | appId: process.env.REACT_APP_APP_ID 14 | }; 15 | 16 | class Firebase { 17 | constructor() { 18 | app.initializeApp(config); 19 | 20 | // Firebase kimlik kontrolü ve database objesi 21 | this.auth = app.auth(); 22 | this.database = app.database(); 23 | } 24 | 25 | // TIP: Firebase güvenilirlik işlemleri 26 | // Daha fazlası için: https://firebase.google.com/docs/auth/web/start 27 | 28 | doCreateUserWithEmailAndPassword = (email, password) => 29 | this.auth.createUserWithEmailAndPassword(email, password); 30 | 31 | doSignInWithEmailAndPassword = (email, password) => 32 | this.auth.signInWithEmailAndPassword(email, password); 33 | 34 | doSignOut = () => this.auth.signOut(); 35 | 36 | doPasswordReset = email => this.auth.sendPasswordResetEmail(email); 37 | doPasswordUpdate = password => this.auth.currentUser.updatePassword(password); 38 | 39 | // TIP: Firebase kullanıcı işlemleri (user API) 40 | // In Firebase, the RESTful URI becomes a simple path, and the HTTP methods become Firebase’s API. 41 | user = uid => this.database.ref(`users/${uid}`); 42 | users = () => this.database.ref(`users`); 43 | } 44 | 45 | export default Firebase; 46 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 22 | React App 23 | 24 | 25 | 26 |
27 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/components/PasswordChange/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | 3 | import { withFirebase } from "../Firebase"; 4 | 5 | const INITIAL_STATE = { 6 | passwordOne: "", 7 | passwordTwo: "", 8 | error: null 9 | }; 10 | 11 | class PasswordChangeForm extends Component { 12 | constructor(props) { 13 | super(props); 14 | 15 | this.state = { ...INITIAL_STATE }; 16 | } 17 | 18 | onSubmit = event => { 19 | const { passwordOne } = this.state; 20 | 21 | this.props.firebase 22 | .doPasswordUpdate(passwordOne) 23 | .then(() => { 24 | this.setState({ ...INITIAL_STATE }); 25 | }) 26 | .catch(error => { 27 | this.setState({ error }); 28 | }); 29 | 30 | event.preventDefault(); 31 | }; 32 | 33 | onChange = event => { 34 | this.setState({ [event.target.name]: event.target.value }); 35 | }; 36 | 37 | render() { 38 | const { passwordOne, passwordTwo, error } = this.state; 39 | 40 | const isInvalid = passwordOne !== passwordTwo || passwordOne === ""; 41 | 42 | return ( 43 |
44 | 51 | 58 | 61 | 62 | {error &&

{error.message}

} 63 |
64 | ); 65 | } 66 | } 67 | 68 | export default withFirebase(PasswordChangeForm); 69 | -------------------------------------------------------------------------------- /src/components/Admin/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | 3 | import { withAuthorization } from "../Session"; 4 | 5 | class AdminPage extends Component { 6 | constructor(props) { 7 | super(props); 8 | 9 | this.state = { 10 | loading: false, 11 | users: [] 12 | }; 13 | } 14 | 15 | componentDidMount() { 16 | this.setState({ loading: true }); 17 | 18 | // TIP: Her kullanıcı işlemi olduğunda çalışır 19 | // WARN: users(), component unmount olduğunda kaldırlmazsa performans kaybına neden olur. 20 | this.props.firebase.users().on("value", snapshot => { 21 | const userObject = snapshot.val(); 22 | 23 | // Her user öğesini listeye kaydetme 24 | const userList = Object.keys(userObject).map(key => ({ 25 | ...userObject[key], 26 | uid: key 27 | })); 28 | 29 | this.setState({ 30 | users: userList, 31 | loading: false 32 | }); 33 | }); 34 | } 35 | 36 | componentWillUnmount() { 37 | this.props.firebase.users().off(); 38 | } 39 | 40 | render() { 41 | const { users, loading } = this.state; 42 | 43 | return ( 44 |
45 |

Admin

46 | {loading &&
Loading ...
} 47 | 48 |
49 | ); 50 | } 51 | } 52 | 53 | const UserList = ({ users }) => ( 54 | 69 | ); 70 | 71 | const condition = authUser => !!authUser; 72 | 73 | export default withAuthorization(condition)(AdminPage); 74 | -------------------------------------------------------------------------------- /src/components/PasswordForget/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { Link } from "react-router-dom"; 3 | 4 | import { withFirebase } from "../Firebase"; 5 | import * as ROUTES from "../constants/routes"; 6 | 7 | const PasswordForgetPage = () => ( 8 |
9 |

PasswordForget

10 | 11 |
12 | ); 13 | 14 | const INITIAL_STATE = { 15 | email: "", 16 | error: null 17 | }; 18 | 19 | class PasswordForgetFormBase extends Component { 20 | constructor(props) { 21 | super(props); 22 | 23 | this.state = { ...INITIAL_STATE }; 24 | } 25 | 26 | onSubmit = event => { 27 | const { email } = this.state; 28 | 29 | this.props.firebase 30 | .doPasswordReset(email) 31 | .then(() => { 32 | this.setState({ ...INITIAL_STATE }); 33 | }) 34 | .catch(error => { 35 | this.setState({ error }); 36 | }); 37 | 38 | event.preventDefault(); 39 | }; 40 | 41 | onChange = event => { 42 | this.setState({ [event.target.name]: event.target.value }); 43 | }; 44 | 45 | render() { 46 | const { email, error } = this.state; 47 | 48 | const isInvalid = email === ""; 49 | 50 | return ( 51 |
52 | 59 | 62 | 63 | {error &&

{error.message}

} 64 |
65 | ); 66 | } 67 | } 68 | 69 | const PasswordForgetLink = () => ( 70 |

71 | Forgot Password? 72 |

73 | ); 74 | 75 | export default PasswordForgetPage; 76 | 77 | const PasswordForgetForm = withFirebase(PasswordForgetFormBase); 78 | 79 | export { PasswordForgetForm, PasswordForgetLink }; 80 | -------------------------------------------------------------------------------- /Kişisel Notlar/Y - Projenin Temel İlerleyişi.md: -------------------------------------------------------------------------------- 1 | # Projenin Temel İlerleyişi 2 | 3 | Her yeni fonksiyon için **commit** yapılmıştır, commitler üzerinden takip edebilirsin. 4 | 5 | ## Tamamlanan Kurslar 6 | 7 | 1. [A Firebase in React Tutorial for Beginners](https://www.robinwieruch.de/complete-firebase-authentication-react-tutorial) ✔ 8 | 2. [React Firebase Authorization with Roles](https://www.robinwieruch.de/react-firebase-authorization-roles-permissions) 9 | 3. [React Firebase Auth Persistence with Local Storage](https://www.robinwieruch.de/react-firebase-auth-persistence) 10 | 4. [React Firebase Social Login: Google, Facebook, Twitter](https://www.robinwieruch.de/react-firebase-social-login) 11 | 5. [React Firebase: Link Social Logins](https://www.robinwieruch.de/react-firebase-link-social-logins) 12 | 6. [React Firebase: Email Verification](https://www.robinwieruch.de/react-firebase-email-verification) 13 | 7. [How to use React Router with Firebase](https://www.robinwieruch.de/react-firebase-router) 14 | 8. [How to use Firebase Realtime Database in React](https://www.robinwieruch.de/react-firebase-realtime-database) 15 | 9. [How to deploy a React application to Firebase](https://www.robinwieruch.de/firebase-deploy-react-js) ✔ 16 | 10. [How to use Redux in React Firebase](https://www.robinwieruch.de/react-firebase-redux-tutorial/) 17 | 18 | 19 | ## Firebase ve React ile Giriş İşlemleri 20 | 21 | Kursun sitesi için [A Firebase in React Tutorial for Beginners](https://www.robinwieruch.de/complete-firebase-authentication-react-tutorial/) bakabilirsin. 22 | 23 | - React ve React router temelleri atıldı ⚛ 24 | - Temel navigasyon yapısı oluşturuldu 🧭 25 | - Firebase 🔥 bağlantısı kuruldu 26 | - Firebase 🔥 bağlantısı ve auth işlemleri oluşturuldu 27 | - Giriş yapıldığında sayfa yönlendirmesi ↗ 28 | - Recompose yapısı eklendi 🕯 29 | - Giriş yapma fonksiyonu eklendi 🎟 30 | - Çıkış yapma fonksiyonu eklendi 🚶‍♂️ 31 | - Firebase 🔥 üzerinde oturuma göre işlemler 32 | - React Context API ⚛ ile daha temiz yapı oluşturuldu ✨ 33 | - Şifre sıfırlama alanı eklendi 🔐 34 | - Şifre değiştirme alanı eklendi 🔐 35 | - Koşullu sayfa yönlendirme eklendi 🔐 36 | - Database 📂 temelleri atıldı 37 | - Kullanıcı kayıtları database'e de eklenmekte 📅 38 | - Admin 👨 sayfası eklendi 39 | - Kurs tamamlandı 🚀 40 | - Firebase 🔥 üzerinde sunulmaya başlandı 🌍 41 | - Son notlar eklendi 📄 42 | -------------------------------------------------------------------------------- /src/components/SignIn/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { withRouter } from "react-router-dom"; 3 | import { compose } from "recompose"; 4 | 5 | import { SignUpLink } from "../SignUp"; 6 | import { PasswordForgetLink } from "../PasswordForget"; 7 | 8 | import { withFirebase } from "../Firebase"; 9 | import * as ROUTES from "../constants/routes"; 10 | 11 | const SignInPage = () => ( 12 |
13 |

SignIn

14 | 15 | 16 | 17 |
18 | ); 19 | 20 | const INITIAL_STATE = { 21 | email: "", 22 | password: "", 23 | error: null 24 | }; 25 | 26 | class SignInFormBase extends Component { 27 | constructor(props) { 28 | super(props); 29 | 30 | this.state = { ...INITIAL_STATE }; 31 | } 32 | 33 | onSubmit = event => { 34 | const { email, password } = this.state; 35 | 36 | this.props.firebase 37 | .doSignInWithEmailAndPassword(email, password) 38 | .then(() => { 39 | // TIP: Giriş başarılı olduğunda yapılacaklar 40 | this.setState({ ...INITIAL_STATE }); 41 | this.props.history.push(ROUTES.HOME); 42 | }) 43 | .catch(error => { 44 | // TIP: Giriş başarısız olduğunda yapılacaklar 45 | this.setState({ error }); 46 | }); 47 | 48 | event.preventDefault(); 49 | }; 50 | 51 | onChange = event => { 52 | this.setState({ [event.target.name]: event.target.value }); 53 | }; 54 | 55 | render() { 56 | const { email, password, error } = this.state; 57 | 58 | const isInvalid = password === "" || email === ""; 59 | 60 | return ( 61 |
62 | 69 | 76 | 79 | 80 | {error &&

{error.message}

} 81 |
82 | ); 83 | } 84 | } 85 | 86 | const SignInForm = compose( 87 | withRouter, 88 | withFirebase 89 | )(SignInFormBase); 90 | 91 | export default SignInPage; 92 | 93 | export { SignInForm }; 94 | -------------------------------------------------------------------------------- /Kişisel Notlar/X - Faydalı Kaynaklar.md: -------------------------------------------------------------------------------- 1 | # Faydalı Kaynaklar 2 | 3 | Faydalı olabilecek kaynakları 📰 derlediğim döküman. 4 | 5 | > Çalışma kitapları [Kitaplar 📚](../Kitaplar) dizininde mevcuttur. 6 | 7 | ## İçerikler 8 | 9 | - [Kendi Notlarım ve Yararlandığım Kaynaklar](#Kendi-Notlar%C4%B1m-ve-Yararland%C4%B1%C4%9F%C4%B1m-Kaynaklar) 10 | - [İleride Bakılacaklar](#%C4%B0leride-Bak%C4%B1lacaklar) 11 | - [Çalışma Kaynakları](#%C3%87al%C4%B1%C5%9Fma-Kaynaklar%C4%B1) 12 | - [React Native](#React-Native) 13 | 14 | ## Kendi Notlarım ve Yararlandığım Kaynaklar 15 | 16 | - [A Firebase in React Tutorial for Beginners](https://www.robinwieruch.de/complete-firebase-authentication-react-tutorial/) 17 | - [Firebase Tutorial](https://www.robinwieruch.de/firebase-tutorial/) 18 | - [React Kitapları](https://drive.google.com/open?id=1JFHiLsMys29fGLcYMweU33hExWtyG2zV) 19 | - [Firebase Web İşlemleri](https://firebase.google.com/docs/auth/web/start) 20 | 21 | ## İleride Bakılacaklar 22 | 23 | - [How to fetch data in React](https://www.robinwieruch.de/react-fetching-data/) 24 | - [React's Render Props Pattern - Children as a Function](https://www.robinwieruch.de/react-render-props-pattern/) 25 | - [Reactjs Interview Questions](https://github.com/sudheerj/reactjs-interview-questions) 26 | 27 | ## Çalışma Kaynakları 28 | 29 | 1. [A Firebase in React Tutorial for Beginners](https://www.robinwieruch.de/complete-firebase-authentication-react-tutorial) 30 | 2. [React Firebase Authorization with Roles](https://www.robinwieruch.de/react-firebase-authorization-roles-permissions) 31 | 3. [React Firebase Auth Persistence with Local Storage](https://www.robinwieruch.de/react-firebase-auth-persistence) 32 | 4. [React Firebase Social Login: Google, Facebook, Twitter](https://www.robinwieruch.de/react-firebase-social-login) 33 | 5. [React Firebase: Link Social Logins](https://www.robinwieruch.de/react-firebase-link-social-logins) 34 | 6. [React Firebase: Email Verification](https://www.robinwieruch.de/react-firebase-email-verification) 35 | 7. [How to use React Router with Firebase](https://www.robinwieruch.de/react-firebase-router) 36 | 8. [How to use Firebase Realtime Database in React](https://www.robinwieruch.de/react-firebase-realtime-database) 37 | 9. [How to deploy a React application to Firebase](https://www.robinwieruch.de/firebase-deploy-react-js) 38 | 10. [How to use Redux in React Firebase](https://www.robinwieruch.de/react-firebase-redux-tutorial/) 39 | 40 | ## React Native 41 | 42 | - [Awesome React Native UI](https://github.com/madhavanmalolan/awesome-reactnative-ui) 43 | -------------------------------------------------------------------------------- /Kişisel Notlar/2 - Hızlı Notlar.md: -------------------------------------------------------------------------------- 1 | # Hızlı Notlar 2 | 3 | ## Const ve Class Seçimi 4 | 5 | - Sadece veri `return` ediliyorsa `const` seçilir. 6 | - `{}` yerine `()` kullanılır 7 | 8 | ```jsx 9 | const App = () => ( 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 |
23 | ); 24 | ``` 25 | 26 | ## React Context API 27 | 28 | En üst bileşenlerden en alt bileşenlere veri (`state`) göndermek için her bir bileşenden verinin aktarılması lazım, bu yapı sayesinde veriler direkt olarak aktarılabilmekte 29 | 30 | - Provider 31 | - Consumer 32 | 33 | ### Basit anlamda RCA 34 | 35 | ```jsx 36 | // src/componnet//context.js 37 | import React from "react"; 38 | 39 | const AuthUserContext = React.createContext(null); 40 | 41 | export default AuthUserContext; 42 | ``` 43 | 44 | ```jsx 45 | // src/componnet//index.js 46 | import AuthUserContext from "./context"; 47 | 48 | export { AuthUserContext }; 49 | ``` 50 | 51 | ```jsx 52 | // src/component/App.js 53 | ... 54 | 55 | render() { 56 | 57 |
58 | ... 59 |
60 |
61 | } 62 | ``` 63 | 64 | ```jsx 65 | const Navigation = () => ( 66 | 67 | {authUser => (authUser ? : )} 68 | 69 | ); 70 | ``` 71 | 72 | ### Firebase için RCA 73 | 74 | ```jsx 75 | import React from "react"; 76 | 77 | const FirebaseContext = React.createContext(null); 78 | 79 | // Firebase ile component kullanımı 80 | 81 | /** 82 | * Firebase props'una erişim hakkı ile componenti çağırma 83 | * @param {React.Component} Component Firebase erişimi verilecek React Componenti 84 | */ 85 | export const withFirebase = Component => props => ( 86 | 87 | {firebase => } 88 | 89 | ); 90 | 91 | export default FirebaseContext; 92 | ``` 93 | 94 | ```jsx 95 | import FirebaseContext, { withFirebase } from "./context"; 96 | import Firebase from "./firebase"; 97 | 98 | export default Firebase; 99 | 100 | export { FirebaseContext, withFirebase }; 101 | ``` 102 | 103 | -------------------------------------------------------------------------------- /README-React.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `npm start` 8 | 9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console. 14 | 15 | ### `npm test` 16 | 17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 19 | 20 | ### `npm run build` 21 | 22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance. 24 | 25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed! 27 | 28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 29 | 30 | ### `npm run eject` 31 | 32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 33 | 34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 35 | 36 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 37 | 38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 39 | 40 | ## Learn More 41 | 42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 43 | 44 | To learn React, check out the [React documentation](https://reactjs.org/). 45 | 46 | ### Code Splitting 47 | 48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 49 | 50 | ### Analyzing the Bundle Size 51 | 52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 53 | 54 | ### Making a Progressive Web App 55 | 56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 57 | 58 | ### Advanced Configuration 59 | 60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 61 | 62 | ### Deployment 63 | 64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 65 | 66 | ### `npm run build` fails to minify 67 | 68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 69 | -------------------------------------------------------------------------------- /Kişisel Notlar/0 - Kurulum ve Kullanım.md: -------------------------------------------------------------------------------- 1 | # Kurulum ve Kullanım 2 | 3 | Projenin çalıştırılabilmesi ▶ için gerekli olan işlemleri ve açıklamaları 📃 içerir. 4 | 5 | ## İçerikler 6 | 7 | - [Kullanılan Teknolojiler](#Kullan%C4%B1lan-Teknolojiler) 8 | - [Nodejs ve React Kurulumu](#Nodejs-ve-React-Kurulumu) 9 | - [Bu projenin kurulumu](#Bu-projenin-kurulumu) 10 | - [Sıfırdan Kurulum](#S%C4%B1f%C4%B1rdan-Kurulum) 11 | 12 | ## Kullanılan Teknolojiler 13 | 14 | | Teknoloji | Açıklama | 15 | | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 16 | | [React](https://reactjs.org/) | Facebook'un oluşturmuş olduğun web framework'u | 17 | | [React Router](https://github.com/ReactTraining/react-router) | Her sayfa değişikliğinde yeniden sunucuya istek atılmaz, sadece giriş kısmında tüm sayfalar sunucudan alınır | 18 | | [Firebase](https://firebase.google.com/) | Google'ın sunduğu çok verimli (auth, data storage ...) database sistemi | 19 | | [Recompose](https://github.com/acdlite/recompose) | `withX(withX(withX...(component)))` yapısındaki karmaşıklığı engelleyerek tek metotda (`compose`) kullanmayı sağlar | 20 | | React Context API | En üst bileşenlerden en alt bileşenlere veri (`state`) göndermek için her bir bileşenden verinin aktarılması lazım, bu yapı sayesinde veriler direkt olarak aktarılabilmekte | 21 | 22 | ## Nodejs ve React Kurulumu 23 | 24 | - [Nodejs kurulumu](https://nodejs.org/en/download/) 25 | 26 | ### Bu projenin kurulumu 27 | 28 | - `git clone ` ile bu projeyi indirin 29 | - İndiridiğiniz projenin içine girin `cd YReact-Firebase` 30 | - `npm install` komutu ile gerekli modülleri yüklemeyi başlatın 31 | - Firebase üzerinden bilgilerinizi `.env` dosyası oluşturarak içine yazın 32 | - Detaylı bilgi için **Firebase Kullanımı** alanına bakın 33 | - `.env` dosyası oluşturulmazsa **boş sayfa** gösterecektir 34 | - `npm start` ile kurulumu test edin 35 | 36 | ### Sıfırdan Kurulum 37 | 38 | - `npm install -g create-react-app` 39 | - Projenin oluşturulacağı dizine terminal (`cmd` veya `bash`) ile gelin 40 | - `create-react-app ` yazın 41 | - Örn: `YReact-Firebase` 42 | - `cd ` ile proje dizinine girin 43 | - `npm start` ile projeyi test edin 44 | 45 |
46 | Router için örnek dizin yapısı 47 | 48 | ```sh 49 | cd src 50 | rm App.js App.test.js App.css logo.svg 51 | 52 | mkdir components 53 | cd components 54 | mkdir Account Admin App Home Landing SignIn SignOut SignUp 55 | mkdir Navigation PasswordChange PasswordForget 56 | mkdir Session Firebase 57 | 58 | cd App 59 | touch index.js 60 | cd .. 61 | 62 | mkdir constants 63 | cd constants 64 | touch routes.js roles.js 65 | cd .. 66 | ``` 67 | 68 |
69 | -------------------------------------------------------------------------------- /src/components/SignUp/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { Link, withRouter } from "react-router-dom"; 3 | import { compose } from "recompose"; 4 | 5 | import { withFirebase } from "../Firebase"; 6 | 7 | import * as ROUTES from "../constants/routes"; 8 | 9 | const SignUpPage = () => ( 10 |
11 |

SignUp

12 | 13 |
14 | ); 15 | 16 | const INITIAL_STATE = { 17 | username: "", 18 | email: "", 19 | passwordOne: "", 20 | passwordTwo: "", 21 | error: null 22 | }; 23 | 24 | class SignUpFormBase extends Component { 25 | constructor(props) { 26 | super(props); 27 | 28 | this.state = { ...INITIAL_STATE }; 29 | } 30 | 31 | onSubmit = event => { 32 | const { username, email, passwordOne } = this.state; 33 | this.props.firebase 34 | .doCreateUserWithEmailAndPassword(email, passwordOne) 35 | // TIP: Kayıt başarılı olduğunda yapılacaklar 36 | 37 | // Kullanıcı bilgilerini database'e kaydetme 38 | .then(authUser => { 39 | return this.props.firebase.user(authUser.user.uid).set({ 40 | username, 41 | email 42 | }); 43 | }) 44 | 45 | .then(() => { 46 | this.setState({ ...INITIAL_STATE }); 47 | 48 | // Sayfa yönlendirme işlemi 49 | this.props.history.push(ROUTES.HOME); 50 | }) 51 | 52 | .catch(error => { 53 | // TIP: Kayıt başaarısız olduğunda yapılacaklar 54 | this.setState({ error }); 55 | }); 56 | 57 | // Sayfanın yenilenmesini engeller 58 | event.preventDefault(); 59 | }; 60 | 61 | onChange = event => { 62 | this.setState({ [event.target.name]: event.target.value }); 63 | }; 64 | 65 | render() { 66 | const { username, email, passwordOne, passwordTwo, error } = this.state; 67 | 68 | const isInvalid = 69 | passwordOne !== passwordTwo || 70 | passwordOne === "" || 71 | email === "" || 72 | username === ""; 73 | 74 | return ( 75 |
76 | 83 | 90 | 97 | 104 | 107 | 108 | {error &&

{error.message}

} 109 |
110 | ); 111 | } 112 | } 113 | 114 | // Compose yapısı ile iç içe () olayı engellendi 115 | const SignUpForm = compose( 116 | withRouter, 117 | withFirebase 118 | )(SignUpFormBase); 119 | 120 | const SignUpLink = () => ( 121 |

122 | Don't have an account? Sign Up 123 |

124 | ); 125 | 126 | export default SignUpPage; 127 | export { SignUpLink, SignUpForm }; 128 | -------------------------------------------------------------------------------- /Kişisel Notlar/1 - Firebase İşlemleri.md: -------------------------------------------------------------------------------- 1 | # Firebase 🔥 İşlemleri 2 | 3 | Google'ın sunduğu online database 📅 servisidir. 4 | 5 | ## İçerikler 6 | 7 | - [Firebase Oluşturma](#Firebase-Olu%C5%9Fturma) 8 | - [Firebase Kullanımı](#Firebase-Kullan%C4%B1m%C4%B1) 9 | - [Firebase Database Notları](#Firebase-Database-Notlar%C4%B1) 10 | - [Firebase Üzerineden Sunum (Hosting / Deploy)](#Firebase-%C3%9Czerineden-Sunum-Hosting--Deploy) 11 | - [Firebase için Faydalı Notlar](#Firebase-i%C3%A7in-Faydal%C4%B1-Notlar) 12 | - [Firebase için Yetkiye Göre Sayfa Yönlendirmesi](#Firebase-i%C3%A7in-Yetkiye-G%C3%B6re-Sayfa-Y%C3%B6nlendirmesi) 13 | 14 | ## Firebase Oluşturma 15 | 16 | - [Firebase](https://firebase.google.com/) sitesine **Google Hesabınız** ile giriş yapın 17 | - Gerekli yönergeleri takip edip 18 | - Database oluşturun 19 | - `Add app` alanından **Web** kısmını seçin 20 | - Firebase SDK snipped alanından `Config` kısmını seçin 21 | 22 | ```js 23 | // Örnek config 24 | const firebaseConfig = { 25 | apiKey: "XXXXxxxx", 26 | authDomain: "xxxxXXXX.firebaseapp.com", 27 | databaseURL: "https://xxxXXXX.firebaseio.comm", 28 | projectId: "xxxxXXXX", 29 | storageBucket: "", 30 | messagingSenderId: "xxxxXXXX", 31 | appId: "X:xxxxxxxxxx:xxx:xxxxxxxxx" 32 | }; 33 | ``` 34 | 35 | ## Firebase Kullanımı 36 | 37 | - Firebase bilgileri `.env` adlı dosya ile oluşturulmalıdır 38 | - Projede `process.env` olarak Env dosyaları alınmaktadır. 39 | - Env dosyaları projenin ana dizininde olmalı 40 | - İstersenin tek bir `.env` dosyası ile yönetebilirsiniz 41 | - Ya da özelleştirilmiş olarak kullanılabilir 42 | - `.env.development` 43 | - `.env.production` 44 | 45 | ```env 46 | # Firebase config 47 | REACT_APP_API_KEY=XXXXxxxx 48 | REACT_APP_AUTH_DOMAIN=xxxxXXXX.firebaseapp.com 49 | REACT_APP_DATABASE_URL=https://xxxXXXX.firebaseio.com 50 | REACT_APP_PROJECT_ID=xxxxXXXX 51 | REACT_APP_STORAGE_BUCKET=xxxxXXXX.appspot.com 52 | REACT_APP_MESSAGING_SENDER_ID=xxxxXXXX 53 | REACT_APP_APP_ID=X:xxxxxxxxxx:xxx:xxxxxxxxx 54 | ``` 55 | 56 | ## Firebase Database Notları 57 | 58 | - In Firebase, the RESTful URI becomes a simple path, and the HTTP methods become Firebase’s API. 59 | - [Firebase tutorial](https://www.robinwieruch.de/firebase-tutorial/) 60 | - [Firebase hangi database seçmeliyim?](https://firebase.google.com/docs/database/rtdb-vs-firestore) 61 | - [Firebase fiyatlandırması](https://firebase.google.com/pricing) 62 | 63 | 64 | ## Firebase Üzerineden Sunum (Hosting / Deploy) 65 | 66 | Detaylar için [How to deploy a React application to Firebase](https://www.robinwieruch.de/firebase-deploy-react-js/) sayfasına bakabilirsin. 67 | 68 | | Komut | Açılama | 69 | | --------------- | ---------------------------------------------- | 70 | | firebase login | Firebase'e giriş (Google hesabı ile) | 71 | | firebase init | Firebase'de serilenmeden önce hazırlama eylemi | 72 | | firebase deploy | Firebase üzerinden sunma | 73 | 74 | > [Firebase hosting'i iptal etme](https://stackoverflow.com/a/44584220) 75 | 76 | 77 | ## Firebase için Faydalı Notlar 78 | 79 | Çok sık tercih edilen **Firebase class'ı oluşturup, her _component_ için onu çağırmak** eylemi sorunlara sebeb olur, çünkü: 80 | 81 | - React bileşenlerini test etmesi çok zorlaşır 82 | - Firebase tek seferlik tanımlanması gereken bir sistem içerir (singleton) 83 | - Aksi halde hata eğilimli bir davranış sergiler. 84 | 85 | > [React Context API](https://www.robinwieruch.de/react-context-api/) tercih edilmelidir. Bu sistem ile firebase örneği tüm componentlerin üstünde tanımlar. 86 | 87 | ### Firebase için Yetkiye Göre Sayfa Yönlendirmesi 88 | 89 | ```jsx 90 | // Girişe göre yetkilendirme (const condition = authUser => authUser != null;) 91 | const condition = authUser => !!authUser; 92 | // Rol tabanlı yetkilendirme 93 | const condition = authUser => authUser.role === "ADMIN"; 94 | // İzin tabanlı yetkilendirme 95 | const condition = authUser => authUser.permissions.canEditAccount; 96 | ``` 97 | 98 | 99 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # YReact-Firebase 2 | 3 | React ⚛️, React-Router 🔗 ve Firebase 🔥 projesi ([canlı 🌍](https://yreact-firebase.firebaseapp.com/)) 4 | 5 | > Son tamamlanan kurs: [A Firebase in React Tutorial for Beginners [2019]](https://www.robinwieruch.de/complete-firebase-authentication-react-tutorial/) 6 | 7 | ## İçerikler 8 | 9 | - [Açıklama](#A%C3%A7%C4%B1klama) 10 | - [Ek Notlar](#Ek-Notlar) 11 | - [Çalıştırıldığında boş sayfa gözükmesi](#%C3%87al%C4%B1%C5%9Ft%C4%B1r%C4%B1ld%C4%B1%C4%9F%C4%B1nda-bo%C5%9F-sayfa-g%C3%B6z%C3%BCkmesi) 12 | - [TODO-Tree Yapılandırması](#TODO-Tree-Yap%C4%B1land%C4%B1rmas%C4%B1) 13 | - [Destek ve İletişim](#Destek-ve-%C4%B0leti%C5%9Fim) 14 | 15 | ## Açıklama 16 | 17 | - [Projenin temel ilerleyişi 🚶‍♂️](Kişisel%20Notlar/Y%20-%20Projenin%20Temel%20İlerleyişi.md) için **commit**'leri veya açıklama dosyama bakabilirsin. 18 | - Kişisel notlarım [Kişisel Notlar 📔](Ki%C5%9Fisel%20Notlar) dizinindedir 19 | - Faydalı kitaplar [Kitaplar 📚](Kitaplar) dizinindedir. 20 | - Faydalı kaynaklar listem için [buraya 🌟](Kişisel%20Notlar/X%20-%20Faydalı%20Kaynaklar.md) bakabilirsin. 21 | 22 | > Data Science notlarım için [YDataScience 📊](https://github.com/yedhrab/YDataScience) _repository_'isine bakabilirsin. 23 | 24 | ## Ek Notlar 25 | 26 | ### Çalıştırıldığında boş sayfa gözükmesi 27 | 28 | - `.env` dosyanızı koyamazsanız firebase'e bağlanılamayacağından boş sayfa gözükecektir 29 | 30 | ### TODO-Tree Yapılandırması 31 | 32 | ![](res/todo_tree.png) 33 | 34 |
35 | Yapılandırmayı göster 36 | 37 | ```json 38 | { 39 | // Todo-Tree ayarları 40 | "todo-tree.tags": [ 41 | "TODO:", 42 | "BUG:", 43 | "DEV:", 44 | "RES:", 45 | "OLD:", 46 | "WARN:", 47 | "TIP:" 48 | ], 49 | "todo-tree.labelFormat": "${after}", // (${line}) 50 | "todo-tree.grouped": true, 51 | "todo-tree.tagsOnly": true, 52 | "todo-tree.excludeGlobs": [ 53 | "**/*.json" 54 | ], 55 | "todo-tree.defaultHighlight": { 56 | "icon": "tasklist", 57 | "type": "text", 58 | "background": "#6FA5FF", 59 | "opacity": 17, 60 | "iconColour": "#6FA5FF" 61 | }, 62 | "todo-tree.customHighlight": { 63 | // TIP: Bilgiler (tip) 64 | "TIP:": { 65 | "icon": "book", 66 | "type": "text", 67 | "foreground": "#f5f2a9", 68 | "background": "#f5f2a9", 69 | "opacity": 7, 70 | "iconColour": "#f5f2a9" 71 | }, 72 | // TODO:: Yapılacak (todo) 73 | "TODO:": { 74 | "icon": "checklist", 75 | "type": "text", 76 | "fontStyle": "normal", 77 | "foreground": "#6FA5FF", 78 | "background": "#6FA5FF", 79 | "opacity": 7, 80 | "iconColour": "#6FA5FF" 81 | }, 82 | // BUG: Hatalar (bug) 83 | "BUG:": { 84 | "icon": "bug", 85 | "type": "text", 86 | "foreground": "#FF2C2C", 87 | "background": "#FF2C2C", 88 | "opacity": 7, 89 | "iconColour": "#FF2C2C" 90 | }, 91 | // DEV: İyileştirme, geliştirme (dev) 92 | "DEV:": { 93 | "icon": "telescope", 94 | "type": "text", 95 | "foreground": "#72CB6A", 96 | "background": "#72CB6A", 97 | "opacity": 7, 98 | "iconColour": "#72CB6A" 99 | }, 100 | // RES: Gelecek planları, araştırmalar (res) 101 | "RES:": { 102 | "icon": "beaker", 103 | "type": "text", 104 | "foreground": "#9CF7FF", 105 | "background": "#9CF7FF", 106 | "opacity": 7, 107 | "iconColour": "#9CF7FF" 108 | }, 109 | // WARN: Uyarılar (warn) 110 | "WARN:": { 111 | "icon": "megaphone", 112 | "type": "text", 113 | "foreground": "#CFCC35", 114 | "background": "#CFCC35", 115 | "opacity": 7, 116 | "iconColour": "#CFCC35" 117 | }, 118 | // OLD: Eskimiş, kaldırılacak (deprecated) 119 | "OLD:": { 120 | "icon": "trashcan", 121 | "type": "text", 122 | "foreground": "#959595", 123 | "background": "#959595", 124 | "opacity": 7, 125 | "iconColour": "#959595" 126 | } 127 | }, 128 | } 129 | ``` 130 | 131 |
132 | 133 | ## Destek ve İletişim 134 | 135 | **The [MIT License](https://choosealicense.com/licenses/mit/) © Yunus Emre Ak** 136 | 137 | [![Github](https://drive.google.com/uc?id=1PzkuWOoBNMg0uOMmqwHtVoYt0WCqi-O5)][github] 138 | [![LinkedIn](https://drive.google.com/uc?id=1hvdil0ZHVEzekQ4AYELdnPOqzunKpnzJ)][linkedin] 139 | [![Website](https://drive.google.com/uc?id=1wR8Ph0FBs36ZJl0Ud-HkS0LZ9b66JBqJ)][website] 140 | [![Mail](https://drive.google.com/uc?id=142rP0hbrnY8T9kj_84_r7WxPG1hzWEcN)][mail] 141 | [![Destek](https://drive.google.com/uc?id=1zyU7JWlw4sJTOx46gJlHOfYBwGIkvMQs)][bağış anlık] 142 | 143 | [![Patreon](https://drive.google.com/uc?id=11YmCRmySX7v7QDFS62ST2JZuE70RFjDG)][bağış aylık] 144 | 145 | 146 | 147 | [mail]: mailto::yedhrab@gmail.com?subject=YBilgiler%20%7C%20Github 148 | [github]: https://github.com/yedhrab 149 | [website]: https://yemreak.com 150 | [linkedin]: https://www.linkedin.com/in/yemreak/ 151 | [bağış anlık]: https://gogetfunding.com/yemreak/ 152 | [bağış aylık]: https://www.patreon.com/yemreak/ 153 | 154 | 155 | -------------------------------------------------------------------------------- /src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === "localhost" || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === "[::1]" || 17 | // 127.0.0.1/8 is considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) { 25 | // The URL constructor is available in all browsers that support SW. 26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 27 | if (publicUrl.origin !== window.location.origin) { 28 | // Our service worker won't work if PUBLIC_URL is on a different origin 29 | // from what our page is served on. This might happen if a CDN is used to 30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 31 | return; 32 | } 33 | 34 | window.addEventListener("load", () => { 35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 36 | 37 | if (isLocalhost) { 38 | // This is running on localhost. Let's check if a service worker still exists or not. 39 | checkValidServiceWorker(swUrl, config); 40 | 41 | // Add some additional logging to localhost, pointing developers to the 42 | // service worker/PWA documentation. 43 | navigator.serviceWorker.ready.then(() => { 44 | console.log( 45 | "This web app is being served cache-first by a service " + 46 | "worker. To learn more, visit https://bit.ly/CRA-PWA" 47 | ); 48 | }); 49 | } else { 50 | // Is not localhost. Just register service worker 51 | registerValidSW(swUrl, config); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | function registerValidSW(swUrl, config) { 58 | navigator.serviceWorker 59 | .register(swUrl) 60 | .then(registration => { 61 | registration.onupdatefound = () => { 62 | const installingWorker = registration.installing; 63 | if (installingWorker == null) { 64 | return; 65 | } 66 | installingWorker.onstatechange = () => { 67 | if (installingWorker.state === "installed") { 68 | if (navigator.serviceWorker.controller) { 69 | // At this point, the updated precached content has been fetched, 70 | // but the previous service worker will still serve the older 71 | // content until all client tabs are closed. 72 | console.log( 73 | "New content is available and will be used when all " + 74 | "tabs for this page are closed. See https://bit.ly/CRA-PWA." 75 | ); 76 | 77 | // Execute callback 78 | if (config && config.onUpdate) { 79 | config.onUpdate(registration); 80 | } 81 | } else { 82 | // At this point, everything has been precached. 83 | // It's the perfect time to display a 84 | // "Content is cached for offline use." message. 85 | console.log("Content is cached for offline use."); 86 | 87 | // Execute callback 88 | if (config && config.onSuccess) { 89 | config.onSuccess(registration); 90 | } 91 | } 92 | } 93 | }; 94 | }; 95 | }) 96 | .catch(error => { 97 | console.error("Error during service worker registration:", error); 98 | }); 99 | } 100 | 101 | function checkValidServiceWorker(swUrl, config) { 102 | // Check if the service worker can be found. If it can't reload the page. 103 | fetch(swUrl) 104 | .then(response => { 105 | // Ensure service worker exists, and that we really are getting a JS file. 106 | const contentType = response.headers.get("content-type"); 107 | if ( 108 | response.status === 404 || 109 | (contentType != null && contentType.indexOf("javascript") === -1) 110 | ) { 111 | // No service worker found. Probably a different app. Reload the page. 112 | navigator.serviceWorker.ready.then(registration => { 113 | registration.unregister().then(() => { 114 | window.location.reload(); 115 | }); 116 | }); 117 | } else { 118 | // Service worker found. Proceed as normal. 119 | registerValidSW(swUrl, config); 120 | } 121 | }) 122 | .catch(() => { 123 | console.log( 124 | "No internet connection found. App is running in offline mode." 125 | ); 126 | }); 127 | } 128 | 129 | export function unregister() { 130 | if ("serviceWorker" in navigator) { 131 | navigator.serviceWorker.ready.then(registration => { 132 | registration.unregister(); 133 | }); 134 | } 135 | } 136 | --------------------------------------------------------------------------------