Flutter : starting the app with welcome page - firebase

I'm new to flutter and in my new project I've created a welcome screen that have 2 buttons either login or sign up , I'm using a Wrapper for the authentication and a toggle to navigate between login and sign up ... every thing works fine , but once the app lunches it shows the login screen not the welcome screen !
here is my wrapper class
class wrapper extends StatelessWidget {
const wrapper({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final userModel = Provider.of<UserModel?>(context);
// either home or login page
if(userModel == null){
return const Authenticate();
}else{
return const Home();
}
}
}
and here is my main
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return StreamProvider<UserModel?>.value(
initialData: null,
value: Authentication().onAuthStateChanged,
builder: (context, snapshot) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Auth',
theme: ThemeData(
primaryColor: kPrimaryColor,
scaffoldBackgroundColor: Colors.white,
textTheme: GoogleFonts.nunitoTextTheme(),
),
home: wrapper(),
);
}
);
}
}
the authenticate class :
class Authenticate extends StatefulWidget {
const Authenticate({Key? key}) : super(key: key);
#override
_AuthenticateState createState() => _AuthenticateState();
}
class _AuthenticateState extends State<Authenticate> {
bool showSignIn = true ;
void toggleView() {
setState(() {
showSignIn = !showSignIn;
});
}
#override
Widget build(BuildContext context) {
if(showSignIn){
return LoginScreen(toggleView : toggleView);
}else{
return SignUpScreen(toggleView : toggleView);
}
}
}
welcome screen :
class WelcomeScreen extends StatelessWidget {
const WelcomeScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const Scaffold(
body: Body(),
);
}
}
Body :
class Body extends StatelessWidget {
const Body({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Container(
height: size.height,
width: double.infinity,
color: Color(0xFFA9D7CC),
child:Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(width: size.width,height: 70),
SvgPicture.asset(
"assets/images/recycle.svg" ,
width:441.4,
height: 294 ,
),
const Padding(
padding: EdgeInsets.fromLTRB(20, 40, 7, 0),
child:
Text("lets make saving the planet easy !",
style: TextStyle(
fontSize: 48 ,
fontWeight: FontWeight.bold,
color: Colors.white
),
),
),
const Padding(
padding: EdgeInsets.fromLTRB(27, 10, 110, 0),
child:
Text("start recycling and earn some money ",
style: TextStyle(
fontSize: 20 ,
fontWeight: FontWeight.normal,
color: Colors.white
),
),
),
SizedBox(width: size.width,height: 70),
// login button
SizedBox(
width: 297,
height: 71,
child: ElevatedButton(
style:ElevatedButton.styleFrom(
primary: kPrimaryPopColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40)
)
) ,
onPressed: (){},
child: const Text("login",
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold
),)),
),
//sign up button
SizedBox(
height: 70,
child: TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
),
onPressed: () {},
child: const Text('sign up',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),),
),
)
],
),
);
}
}

Your code in not full. Try to debug
https://docs.flutter.dev/development/tools/devtools/debugger
It seems to me, that here is true
if(userModel == null){
return const Authenticate();

Related

Edit User Profile Page and Profile Picture. Using Real-Time Database flutter

I am trying to pull user data from my UserProfileBrowse Data model and display it on my user profile edit page. Including the image. I also want to update the data into my real-time Database.
THIS IS MY DATA MODEL
class UserProfileBrowse {
String userId;
int age;
String name;
String email;
String imageUrl;
UserProfileBrowse(
this.userId,
this.age,
this.name,
this.email,
this.imageUrl,
);
Map<dynamic, dynamic> toJson() => <dynamic, dynamic>{
'userId': userId,
'age': age,
'name': name,
'email': email,
'imageUrl' : imageUrl,
};
}
THIS IS MY USER PROFILE EDIT PAGE
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../services/auth.dart';
import 'home.dart';
import 'settings.dart';
import 'package:shadow_app_project/data_models/user_profile_browse.dart';
import 'package:shadow_app_project/image_selection/user_edit_image.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
class SettingsUI extends StatelessWidget {
const SettingsUI({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
title: "Setting UI",
home: EditProfilePage(),
);
}
}
class EditProfilePage extends StatefulWidget {
const EditProfilePage({Key? key}) : super(key: key);
#override
_EditProfilePageState createState() => _EditProfilePageState();
}
class _EditProfilePageState extends State<EditProfilePage> {
String currentUser = (Auth().auth.currentUser as User).email.toString();
TextEditingController displayNameController = TextEditingController();
TextEditingController ageController = TextEditingController();
bool isLoading = false;
User? user;
UserProfileBrowse? userModel;
String? imageUrl;
final refDatabase = FirebaseDatabase.instance;
bool showPassword = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
elevation: 1,
leading: IconButton(
icon: const Icon(
Icons.arrow_back,
color: Colors.green,
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => const SettingsPage()));
},
),
actions: [
IconButton(
icon: const Icon(
Icons.settings,
color: Colors.green,
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => const SettingsPage()));
},
),
],
),
body: Container(
padding: const EdgeInsets.only(left: 16, top: 25, right: 16),
child: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: ListView(
children: [
const Text(
"Edit Profile",
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
),
const SizedBox(
height: 15,
),
Container(
width: 130,
height: 130,
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Theme.of(context).scaffoldBackgroundColor),
boxShadow: [
BoxShadow(
spreadRadius: 2,
blurRadius: 10,
color: Colors.black.withOpacity(0.1),
offset: const Offset(0, 10))
],
shape: BoxShape.circle,
image: const DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
"https://images.pexels.com/photos/3307758/pexels-photo-3307758.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=250",
))),
),
const SizedBox(
height: 35,
),
TextField(
decoration: const InputDecoration(
labelText: "Name",
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.teal)),
hintText: 'Input Name',
),
controller: displayNameController,
keyboardType: TextInputType.name,
),
TextField(
decoration: const InputDecoration(
labelText: "Age",
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.teal)),
hintText: 'Input Age',
),
controller: ageController,
//
keyboardType: TextInputType.number,
),
const Padding(
padding: EdgeInsets.all(8.0),
child: Text("Email: ", style: TextStyle(fontSize: 20),),
),
const SizedBox(
height: 35,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
onPressed: () {},
child: const Text("CANCEL",
style: TextStyle(
fontSize: 14,
letterSpacing: 2.2,
color: Colors.black)),
),
TextButton(
onPressed: () {
FirebaseDatabase.instance.ref()
.child('useProfileBrowse')
.child(user!.uid)
.update({
'name': displayNameController.text //yes I know.
});
FirebaseDatabase.instance.ref()
.child('useProfileBrowse')
.child(user!.uid)
.update({
'age': ageController.text //yes I know.
});
},
child: const Text(
"SAVE",
style: TextStyle(
fontSize: 14,
letterSpacing: 2.2,
color: Colors.white),
),
)
],
)
],
),
),
),
);
}
}
I am thinking to use a StreamBuilder in my body: with stream: FirebaseDatabase.instance.ref().child('userProfileBrowse').child(user!.uid).onValue,
Any idea how can I display User profile Imageurl, name, and age from my real-time Database
And also edit the information using stream builder or any other method
I have just coded the UI for my profile edit page. I just want someone to help me retrieve data from my data model class and display it on my user edit page. A single line to display just a name from my data model will help a lot to understand how retrieving data works. I have already saved data(imageUrl, name, age) into my data models during the signup process. Just want to display it
full example with StreamProvider :
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Person {
Person({required this.name, required this.initialAge});
final String name;
final int initialAge;
Stream<String> get age async* {
var i = initialAge;
while (i < 85) {
await Future.delayed(const Duration(seconds: 1), () {
i++;
});
yield i.toString();
}
}
}
void main() {
runApp(
StreamProvider<String>(
create: (_) => Person(name: 'Yohan', initialAge: 25).age,
initialData: 25.toString(),
catchError: (_, error) => error.toString(),
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Future Provider"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Consumer<String>(
builder: (context, String age, child) {
return Column(
children: <Widget>[
const Text("Watch Yohan Age..."),
const Text("name: Yohan"),
Text("age: $age"),
],
);
},
),
),
),
);
}
}
You already started to use the Provider as a state management, so I'd recommend using StreamProvider like this:
StreamProvider<String>(
create: (_) => Profile(name: 'Yohan', initialImageURL: ''),
initialData: ''.toString(),
catchError: (_, error) => error.toString(),
child: child(),
builder: (context) {
// Pretend this is loading data and reporting the percent loaded.
},
),
)
or you can just notify the UI every time you have got a change from the firebase using ChangeNotifier,
for examples, visit Docs

Unable to retrieve data from Firebase Realtime Database in Flutter Application [duplicate]

I am trying to create a simple app that adds posts to a firebase realtime database and shows them on a listview in flutter, but when I "post" it to the database, on the firebase console, the data value constantly appears as null. does anyone know what is wrong?
Here is a bit of my code -
post.dart
class Post {
Image coverImg;
File audioFile;
String body;
String author;
Set usersLiked = {};
DatabaseReference _id;
Post(this.body, this.author);
void likePost(User user) {
if (this.usersLiked.contains(user.uid)) {
this.usersLiked.remove(user.uid);
} else {
this.usersLiked.add(user.uid);
}
}
void update() {
updatePost(this, this._id);
}
void setId(DatabaseReference id) {
this._id = id;
}
Map<String, dynamic> toJson() {
return {
'body': this.body,
'author': this.author,
'usersLiked': this.usersLiked.toList()
};
}
}
Post createPost(record) {
Map<String, dynamic> attributes = {
'author': '',
'usersLiked': [],
'body': ''
};
record.forEach((key, value) => {attributes[key] = value});
Post post = new Post(attributes['body'], attributes['author']);
post.usersLiked = new Set.from(attributes['usersLiked']);
return post;
}
class PostList extends StatefulWidget {
final List<Post> listItems;
final User user;
PostList(this.listItems, this.user);
#override
_PostListState createState() => _PostListState();
}
class _PostListState extends State<PostList> {
void like(Function callBack) {
this.setState(() {
callBack();
});
}
#override
void initState() {
super.initState();
}
#override
void dispose() {
super.dispose();
}
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: this.widget.listItems.length,
itemBuilder: (context, index) {
var post = this.widget.listItems[index];
return Card(
elevation: 7.0,
color: Colors.white,
child: Column(
children: [
Row(
children: [
IconButton(
icon: Icon(
Icons.play_circle_outline,
color: Colors.black,
size: 30,
),
onPressed: () {},
),
Expanded(
child: ListTile(
title: Text(post.body,
style: TextStyle(
fontWeight: FontWeight.w600,
color: Colors.black)),
subtitle: Text(post.author,
style: TextStyle(color: Colors.black)),
),
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(post.usersLiked.length.toString(),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w600)),
IconButton(
icon: Icon(
Icons.thumb_up,
color: post.usersLiked.contains(widget.user.uid)
? Colors.blue
: Colors.black,
),
onPressed: () =>
this.like(() => post.likePost(widget.user)),
)
],
))
],
)
],
));
},
);
}
}
database.dart
final databaseReference = FirebaseDatabase.instance.reference();
DatabaseReference savePost(Post post) {
var id = databaseReference.child('posts/').push();
id.set(post.toJson());
return id;
}
void updatePost(Post post, DatabaseReference id) {
id.update(post.toJson());
}
Future<List<Post>> getAllPosts() async {
DataSnapshot dataSnapshot = await databaseReference.child('posts/').once();
List<Post> posts = [];
if (dataSnapshot.value != null) {
dataSnapshot.value.forEach((key, value) {
Post post = createPost(value);
post.setId(databaseReference.child('posts/' + key));
posts.add(post);
});
}
return posts;
}
home.dart
class UserInfoScreen extends StatefulWidget {
const UserInfoScreen({Key key, User user})
: _user = user,
super(key: key);
final User _user;
#override
_UserInfoScreenState createState() => _UserInfoScreenState();
}
class _UserInfoScreenState extends State<UserInfoScreen> {
User _user;
bool _isSigningOut = false;
List<Post> posts = [];
void newPost(String text) {
var post = new Post(text, widget._user.displayName);
post.setId(savePost(post));
this.setState(() {
posts.add(post);
});
}
void updatePosts() {
getAllPosts().then((posts) => {
this.setState(() {
this.posts = posts;
})
});
}
Route _routeToSignInScreen() {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => SignInScreen(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
var begin = Offset(-1.0, 0.0);
var end = Offset.zero;
var curve = Curves.ease;
var tween =
Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
);
}
#override
void initState() {
_user = widget._user;
// HOME PAGE
pageList.add(Scaffold(
backgroundColor: Colors.white,
body: Column(children: [
Expanded(
child: PostList(this.posts, _user),
),
]),
));
pageList.add(Test1());
pageList.add(Scaffold(
backgroundColor: Colors.white,
body: Column(
children: [
TextInputWidget(this.newPost, "Title:"),
],
),
));
pageList.add(Test3());
// ACCOUNT PAGE
pageList.add(
Scaffold(
backgroundColor: Colors.white,
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(),
_user.photoURL != null
? ClipOval(
child: Material(
color: Colors.grey.withOpacity(0.3),
child: Image.network(
_user.photoURL,
fit: BoxFit.fitHeight,
),
),
)
: ClipOval(
child: Material(
color: Colors.grey.withOpacity(0.3),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Icon(
Icons.person,
size: 60,
color: Colors.black,
),
),
),
),
SizedBox(height: 16.0),
Text(
'${_user.displayName}',
style: TextStyle(
color: Colors.black,
fontSize: 26,
fontWeight: FontWeight.w700),
),
SizedBox(height: 8.0),
Text(
' ${_user.email} ',
style: TextStyle(
color: Colors.black,
fontSize: 20,
letterSpacing: 0.5,
),
),
SizedBox(height: 60.0),
_isSigningOut
? CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
)
: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
Colors.redAccent,
),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
onPressed: () async {
setState(() {
_isSigningOut = true;
});
await Authentication.signOut(context: context);
setState(() {
_isSigningOut = false;
});
Navigator.of(context)
.pushReplacement(_routeToSignInScreen());
},
child: Padding(
padding: EdgeInsets.only(top: 8.0, bottom: 8.0),
child: Text(
'Logout',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
color: Colors.white,
),
),
),
),
],
),
),
);
super.initState();
updatePosts();
}
#override
List<Widget> pageList = List<Widget>();
int _currentIndex = 0;
void onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0.0,
backgroundColor: Colors.white,
title: Text(
'SoundFX',
style: TextStyle(color: Colors.black),
),
centerTitle: true,
),
body: IndexedStack(
index: _currentIndex,
children: pageList,
),
bottomNavigationBar: BottomNavigationBar(
unselectedItemColor: Colors.grey,
selectedItemColor: Colors.blue,
backgroundColor: Colors.white,
elevation: 19.0,
onTap: onTabTapped,
currentIndex: _currentIndex,
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.home),
title: Container(
height: 1.0,
)),
BottomNavigationBarItem(
icon: new Icon(Icons.search),
title: Container(
height: 1.0,
)),
BottomNavigationBarItem(
icon: new Icon(
Icons.add_circle,
size: 40,
),
title: Container(
height: 1.0,
)),
BottomNavigationBarItem(
icon: new Icon(Icons.videocam),
title: Container(
height: 1.0,
)),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
title: Container(
height: 1.0,
)),
],
),
);
}
}
class Test1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.green,
);
}
}
class Test2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
);
}
}
class Test3 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
);
}
}
text-input.dart
class TextInputWidget extends StatefulWidget {
final Function(String) callback;
String label;
TextInputWidget(this.callback, this.label);
#override
_TextInputWidgetState createState() => _TextInputWidgetState();
}
class _TextInputWidgetState extends State<TextInputWidget> {
final controller = TextEditingController();
#override
void dispose() {
super.dispose();
controller.dispose();
}
void click() {
widget.callback(controller.text);
FocusScope.of(context).unfocus();
controller.clear();
}
void pickFiles() async {
FilePickerResult result =
await FilePicker.platform.pickFiles(type: FileType.any);
File file = File(result.files.first.path);
print(file);
}
#override
Widget build(BuildContext context) {
return Container(
height: 400,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: Container(
padding: EdgeInsets.all(20.0),
child: TextField(
controller: this.controller,
decoration: InputDecoration(
labelText: this.widget.label,
))),
),
Container(
child: ElevatedButton(onPressed: this.click, child: Text('Post')),
),
Container(
child:
ElevatedButton(onPressed: this.pickFiles, child: Text('test')),
)
],
),
);
}
}
PS: Also, note that some of the functions and classes are unused or basically useless, and some of the names are very stupid, but please do not comment on those if they are not related to the question, as those are just for some tests for features for me to add into the application.
Also, note that i followed this tutorial - https://www.youtube.com/playlist?list=PLzMcBGfZo4-knQWGK2IC49Q_5AnQrFpzv
firebaser here
Most likely the Firebase SDK is unable to read the URL of the database from its config file, because your database is hosted outside of the default (US) region.
If that is indeed the cause, you should specify the database URL in your code. By specifying it in your code, the SDK should able to connect to the database instance no matter what region it is hosted in.
This mean you should get your database with
FirebaseDatabase("your database URL").reference()
// Or
FirebaseDatabase(databaseURL: "your database URL").reference()
instead of
FirebaseDatabase.instance.reference()
This is documented here:
To get a reference to a database other than a us-central1 default dstabase, you must pass the database URL to getInstance() (or Kotlin+KTX database()) . For a us-central1 default database, you can call getInstance() (or database) without arguments.
So while this is documented, it is incredibly easy to overlook. I'm checking with our team if there's something we can do to make this configuration problem more obvious.

Get users First Letter of First Name in Flutter with Firebase?

I have got the user's first name fine, but I'm wondering how I can create an icon using the user's first letter in their name. See attached the UI.
See code below.
User Profile UI
User Profile Page Screen
BlocBuilder(
cubit: BlocProvider.of<UserBloc>(context),
builder: (context, User user) {
return Text(
(user == null || user.firstName == null)
? 'Welcome'
: '${user.firstName}',
style: TextStyle(
fontFamily: 'Helvetica Neue',
fontSize: 25,
color: const Color(0xff3a4759),
),
textAlign: TextAlign.left,
);
}),
Please note "UserBloc" is not relevant to the question so I haven't included it in this post.
The below code for a Stateless widget will create an Icon according to the UI you showed for reference.
It takes in the parameters:
firstName - The name of the person as String.
backgroundColor- The background colour for the circle enclosing the first letter.
textColor- The colour for the first letter
class NameIcon extends StatelessWidget {
final String firstName;
final Color backgroundColor;
final Color textColor;
const NameIcon(
{Key key, #required this.firstName, this.backgroundColor= Colors.white, this.textColor= Colors.black,})
: super(key: key);
String get firstLetter => this.firstName.substring(0, 1).toUpperCase();
#override
Widget build(BuildContext context) {
return FittedBox(
fit: BoxFit.contain,
alignment: Alignment.center,
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: this.backgroundColor,
border: Border.all(color: Colors.black, width: 0.5),
),
padding: EdgeInsets.all(8.0),
child: Text(this.firstLetter, style: TextStyle(color: this.textColor)),
),
);
}
}
The widget will automatically fit the size and height of the parent widget or a Container, if you want to specify the values explicitly then remove the FittedBox widget and then specify the height and width of the container.
OutPut:
Whole Code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
MyHomePage({Key key, this.title}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.amber,
body: Center(
child: Container(
height: 150.0,
width: 300.0,
child: NameIcon(
firstName: 'Hello',
),
),
),
);
}
}
class NameIcon extends StatelessWidget {
final String firstName;
final Color backgroundColor;
final Color textColor;
const NameIcon(
{Key key, #required this.firstName, this.backgroundColor= Colors.white, this.textColor= Colors.black,})
: super(key: key);
String get firstLetter => this.firstName.substring(0, 1).toUpperCase();
#override
Widget build(BuildContext context) {
return FittedBox(
fit: BoxFit.contain,
alignment: Alignment.center,
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: this.backgroundColor,
border: Border.all(color: Colors.black, width: 0.5),
),
padding: EdgeInsets.all(8.0),
child: Text(this.firstLetter, style: TextStyle(color: this.textColor)),
),
);
}
}
FittedBox(
fit: BoxFit.contain,
alignment: Alignment.center,
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.yellow,
border: Border.all(color: Colors.black, width: 0.5),
),
padding: EdgeInsets.all(8.0),
child: BlocBuilder(
cubit: BlocProvider.of<UserBloc>(context),
builder: (context, User user) {
return Text(
(user == null || user.firstName == null)
? 'Welcome'
: '${user.firstName[0].toUpperCase()}',
style: TextStyle(
fontFamily: 'Helvetica Neue',
fontWeight: FontWeight.bold,
fontSize: 25,
color: const Color(0xff3a4759),
),
textAlign: TextAlign.left,
);
}),
),
),

sucessfully authenticated but can't write in firebase database using flutter [duplicate]

I am trying to create a simple app that adds posts to a firebase realtime database and shows them on a listview in flutter, but when I "post" it to the database, on the firebase console, the data value constantly appears as null. does anyone know what is wrong?
Here is a bit of my code -
post.dart
class Post {
Image coverImg;
File audioFile;
String body;
String author;
Set usersLiked = {};
DatabaseReference _id;
Post(this.body, this.author);
void likePost(User user) {
if (this.usersLiked.contains(user.uid)) {
this.usersLiked.remove(user.uid);
} else {
this.usersLiked.add(user.uid);
}
}
void update() {
updatePost(this, this._id);
}
void setId(DatabaseReference id) {
this._id = id;
}
Map<String, dynamic> toJson() {
return {
'body': this.body,
'author': this.author,
'usersLiked': this.usersLiked.toList()
};
}
}
Post createPost(record) {
Map<String, dynamic> attributes = {
'author': '',
'usersLiked': [],
'body': ''
};
record.forEach((key, value) => {attributes[key] = value});
Post post = new Post(attributes['body'], attributes['author']);
post.usersLiked = new Set.from(attributes['usersLiked']);
return post;
}
class PostList extends StatefulWidget {
final List<Post> listItems;
final User user;
PostList(this.listItems, this.user);
#override
_PostListState createState() => _PostListState();
}
class _PostListState extends State<PostList> {
void like(Function callBack) {
this.setState(() {
callBack();
});
}
#override
void initState() {
super.initState();
}
#override
void dispose() {
super.dispose();
}
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: this.widget.listItems.length,
itemBuilder: (context, index) {
var post = this.widget.listItems[index];
return Card(
elevation: 7.0,
color: Colors.white,
child: Column(
children: [
Row(
children: [
IconButton(
icon: Icon(
Icons.play_circle_outline,
color: Colors.black,
size: 30,
),
onPressed: () {},
),
Expanded(
child: ListTile(
title: Text(post.body,
style: TextStyle(
fontWeight: FontWeight.w600,
color: Colors.black)),
subtitle: Text(post.author,
style: TextStyle(color: Colors.black)),
),
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(post.usersLiked.length.toString(),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w600)),
IconButton(
icon: Icon(
Icons.thumb_up,
color: post.usersLiked.contains(widget.user.uid)
? Colors.blue
: Colors.black,
),
onPressed: () =>
this.like(() => post.likePost(widget.user)),
)
],
))
],
)
],
));
},
);
}
}
database.dart
final databaseReference = FirebaseDatabase.instance.reference();
DatabaseReference savePost(Post post) {
var id = databaseReference.child('posts/').push();
id.set(post.toJson());
return id;
}
void updatePost(Post post, DatabaseReference id) {
id.update(post.toJson());
}
Future<List<Post>> getAllPosts() async {
DataSnapshot dataSnapshot = await databaseReference.child('posts/').once();
List<Post> posts = [];
if (dataSnapshot.value != null) {
dataSnapshot.value.forEach((key, value) {
Post post = createPost(value);
post.setId(databaseReference.child('posts/' + key));
posts.add(post);
});
}
return posts;
}
home.dart
class UserInfoScreen extends StatefulWidget {
const UserInfoScreen({Key key, User user})
: _user = user,
super(key: key);
final User _user;
#override
_UserInfoScreenState createState() => _UserInfoScreenState();
}
class _UserInfoScreenState extends State<UserInfoScreen> {
User _user;
bool _isSigningOut = false;
List<Post> posts = [];
void newPost(String text) {
var post = new Post(text, widget._user.displayName);
post.setId(savePost(post));
this.setState(() {
posts.add(post);
});
}
void updatePosts() {
getAllPosts().then((posts) => {
this.setState(() {
this.posts = posts;
})
});
}
Route _routeToSignInScreen() {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => SignInScreen(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
var begin = Offset(-1.0, 0.0);
var end = Offset.zero;
var curve = Curves.ease;
var tween =
Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
);
}
#override
void initState() {
_user = widget._user;
// HOME PAGE
pageList.add(Scaffold(
backgroundColor: Colors.white,
body: Column(children: [
Expanded(
child: PostList(this.posts, _user),
),
]),
));
pageList.add(Test1());
pageList.add(Scaffold(
backgroundColor: Colors.white,
body: Column(
children: [
TextInputWidget(this.newPost, "Title:"),
],
),
));
pageList.add(Test3());
// ACCOUNT PAGE
pageList.add(
Scaffold(
backgroundColor: Colors.white,
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(),
_user.photoURL != null
? ClipOval(
child: Material(
color: Colors.grey.withOpacity(0.3),
child: Image.network(
_user.photoURL,
fit: BoxFit.fitHeight,
),
),
)
: ClipOval(
child: Material(
color: Colors.grey.withOpacity(0.3),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Icon(
Icons.person,
size: 60,
color: Colors.black,
),
),
),
),
SizedBox(height: 16.0),
Text(
'${_user.displayName}',
style: TextStyle(
color: Colors.black,
fontSize: 26,
fontWeight: FontWeight.w700),
),
SizedBox(height: 8.0),
Text(
' ${_user.email} ',
style: TextStyle(
color: Colors.black,
fontSize: 20,
letterSpacing: 0.5,
),
),
SizedBox(height: 60.0),
_isSigningOut
? CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
)
: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
Colors.redAccent,
),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
onPressed: () async {
setState(() {
_isSigningOut = true;
});
await Authentication.signOut(context: context);
setState(() {
_isSigningOut = false;
});
Navigator.of(context)
.pushReplacement(_routeToSignInScreen());
},
child: Padding(
padding: EdgeInsets.only(top: 8.0, bottom: 8.0),
child: Text(
'Logout',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
color: Colors.white,
),
),
),
),
],
),
),
);
super.initState();
updatePosts();
}
#override
List<Widget> pageList = List<Widget>();
int _currentIndex = 0;
void onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0.0,
backgroundColor: Colors.white,
title: Text(
'SoundFX',
style: TextStyle(color: Colors.black),
),
centerTitle: true,
),
body: IndexedStack(
index: _currentIndex,
children: pageList,
),
bottomNavigationBar: BottomNavigationBar(
unselectedItemColor: Colors.grey,
selectedItemColor: Colors.blue,
backgroundColor: Colors.white,
elevation: 19.0,
onTap: onTabTapped,
currentIndex: _currentIndex,
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.home),
title: Container(
height: 1.0,
)),
BottomNavigationBarItem(
icon: new Icon(Icons.search),
title: Container(
height: 1.0,
)),
BottomNavigationBarItem(
icon: new Icon(
Icons.add_circle,
size: 40,
),
title: Container(
height: 1.0,
)),
BottomNavigationBarItem(
icon: new Icon(Icons.videocam),
title: Container(
height: 1.0,
)),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
title: Container(
height: 1.0,
)),
],
),
);
}
}
class Test1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.green,
);
}
}
class Test2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
);
}
}
class Test3 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
);
}
}
text-input.dart
class TextInputWidget extends StatefulWidget {
final Function(String) callback;
String label;
TextInputWidget(this.callback, this.label);
#override
_TextInputWidgetState createState() => _TextInputWidgetState();
}
class _TextInputWidgetState extends State<TextInputWidget> {
final controller = TextEditingController();
#override
void dispose() {
super.dispose();
controller.dispose();
}
void click() {
widget.callback(controller.text);
FocusScope.of(context).unfocus();
controller.clear();
}
void pickFiles() async {
FilePickerResult result =
await FilePicker.platform.pickFiles(type: FileType.any);
File file = File(result.files.first.path);
print(file);
}
#override
Widget build(BuildContext context) {
return Container(
height: 400,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: Container(
padding: EdgeInsets.all(20.0),
child: TextField(
controller: this.controller,
decoration: InputDecoration(
labelText: this.widget.label,
))),
),
Container(
child: ElevatedButton(onPressed: this.click, child: Text('Post')),
),
Container(
child:
ElevatedButton(onPressed: this.pickFiles, child: Text('test')),
)
],
),
);
}
}
PS: Also, note that some of the functions and classes are unused or basically useless, and some of the names are very stupid, but please do not comment on those if they are not related to the question, as those are just for some tests for features for me to add into the application.
Also, note that i followed this tutorial - https://www.youtube.com/playlist?list=PLzMcBGfZo4-knQWGK2IC49Q_5AnQrFpzv
firebaser here
Most likely the Firebase SDK is unable to read the URL of the database from its config file, because your database is hosted outside of the default (US) region.
If that is indeed the cause, you should specify the database URL in your code. By specifying it in your code, the SDK should able to connect to the database instance no matter what region it is hosted in.
This mean you should get your database with
FirebaseDatabase("your database URL").reference()
// Or
FirebaseDatabase(databaseURL: "your database URL").reference()
instead of
FirebaseDatabase.instance.reference()
This is documented here:
To get a reference to a database other than a us-central1 default dstabase, you must pass the database URL to getInstance() (or Kotlin+KTX database()) . For a us-central1 default database, you can call getInstance() (or database) without arguments.
So while this is documented, it is incredibly easy to overlook. I'm checking with our team if there's something we can do to make this configuration problem more obvious.

return a colored box after button pressed

I'm trying to learn flutter and right now I'm working on buttonclicks.
I have a very easy program below where the integer sum = 5. If the user returns 5 in the textfield and clicks the submit-button my goal is to return a green square below the submit button. If the user prints anything else, the square will be red.
I have actually no idea where to start with this more then I have in my code, so any help that puts me in the right direction is very appreciated. Thank you.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'buttonclicks',
theme: ThemeData(primarySwatch: Colors.deepOrange),
home: FirstClass(),
);
}
}
class FirstClass extends StatefulWidget {
#override
_FirstClassState createState() => _FirstClassState();
}
class _FirstClassState extends State<FirstClass> {
int sum = 5;
String enterAnswer;
void handleCorrect() {
setState(() {
Container(
height: 60.0,
width: 70.0,
decoration: BoxDecoration(color: Colors.green),
child: Text('CORRECT'),
);
});
}
void handleFalse() {
setState(() {
Container(
height: 60.0,
width: 70.0,
decoration: BoxDecoration(color: Colors.red),
child: Text('FALSE'),
);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BUTTON-CLICKS'),
),
body: Container(
child: Center(
child: Column(
children: <Widget>[
Container(
width: 50.0,
child: TextField(
textAlign: TextAlign.center,
autofocus: true,
keyboardType: TextInputType.number,
onChanged: (val) {
enterAnswer = val;
},
),
),
RaisedButton(
child: Text('SUBMIT'),
onPressed: () {
if (enterAnswer.isNotEmpty) {
if (enterAnswer == sum) {
handleCorrect(); //setState
} else {
handleFalse(); //setState
}
}
}),
Container(
//handleCorrect or handleFalse
child: Text("RETURN A GREEN OR A RED BOX"),
),
],
),
),
),
);
}
}
How about something like the following. You should call setState when the button gets clicked and set some state to determine which color to show.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'buttonclicks',
theme: ThemeData(primarySwatch: Colors.deepOrange),
home: FirstClass(),
);
}
}
class FirstClass extends StatefulWidget {
#override
_FirstClassState createState() => _FirstClassState();
}
class _FirstClassState extends State<FirstClass> {
int sum = 5;
String enterAnswer;
Color containerColor;
void setColorForAnswer()
{
setState(() {
containerColor = enterAnswer != null && enterAnswer.isNotEmpty
? (int.parse(enterAnswer) == sum
? Colors.green
: Colors.red)
: Colors.transparent;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BUTTON-CLICKS'),
),
body: Container(
child: Center(
child: Column(
children: <Widget>[
Container(
width: 50.0,
child: TextField(
textAlign: TextAlign.center,
autofocus: true,
keyboardType: TextInputType.number,
onChanged: (val) {
enterAnswer = val;
},
),
),
RaisedButton(
child: Text('SUBMIT'),
onPressed: () {
setColorForAnswer();
}),
Container(
width: 50,
height: 50,
color: containerColor,
),
],
),
),
),
);
}
}

Resources